home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 1996 June / Software of the Month Club 1996 June.iso / pc / dos / dtp / aurora / language.dox < prev    next >
Encoding:
Text File  |  1995-02-24  |  172.3 KB  |  4,447 lines

  1.  
  2.  
  3.   The Aurora Macro Language Reference
  4.   ───────────────────────────────────
  5.   This Reference describes the Aurora Macro Language (AML). For a
  6.   complete description of all builtin and library functions, see the AML
  7.   Function Reference. For information on how to install, configure, and
  8.   use Aurora, see the Aurora Editor Users Guide.
  9.  
  10.   If you are viewing this document with Aurora, you can use the
  11.   'Language Reference Topics' popup menu on the Help menu <f1> to jump
  12.   quickly to any topic in the document.
  13.  
  14.   To transfer to the full AML Function Reference: move the cursor to a
  15.   function name or statement keyword in this reference document and
  16.   press <shift f2>. Note that most extension functions are not
  17.   documented in the AML Function Reference.
  18.  
  19.   ──────────────────────────────────────────────────────────────────────
  20.   Copyright (C) 1995 by nuText Systems.  All rights reserved worldwide.
  21.   No parts of this document may be copied in part or in whole, except as
  22.   provided in the License in the accompanying documentation.
  23.   ──────────────────────────────────────────────────────────────────────
  24.  
  25.  
  26.   Introduction
  27.   ────────────
  28.   The Aurora Macro Language (AML) is the native macro language of The
  29.   Aurora Editor. AML is a flexible, interpreted computer language which
  30.   is easy-to-use, yet powerful and rich in function. Understanding the
  31.   macro language can help you to:
  32.  
  33.     - Tailor the day-to-day operation of the editor to your own
  34.       preferences
  35.     - Modify or add to existing editor functions
  36.     - Create new editor functions
  37.     - Customize detailed aspects of your editing environment
  38.  
  39.   A large base of macro language source and object code is shipped with
  40.   the editor. You can modify the source code to suit your own
  41.   preferences, or you can use the macro language to create your own new
  42.   editor functions.
  43.  
  44.   Although it is easy to use the editor without understanding all the
  45.   details of the macro language, knowledge of the macro language can
  46.   give you a more complete understanding of how the editor actually
  47.   works. Experienced users will find it to be an indispensable tool.
  48.  
  49.  
  50.   Overview
  51.   ────────
  52.   If you browse the directory where the editor is installed, you will
  53.   notice only one executable file: A.EXE. This executable file contains
  54.   all of the builtin functions of the editor, as well as the macro
  55.   language interpreter and compiler.
  56.  
  57.   With the interpreter and compiler both present within an edit session,
  58.   macro language source code can be executed interactively. In fact,
  59.   both the interpreter and the compiler are accessible as builtin
  60.   functions within the macro language itself.
  61.  
  62.   Since the editor is written in its own macro language, it can be
  63.   viewed as one large compiled 'macro' (contained in the file A.X). Much
  64.   of the source code for this macro is shipped with the editor, allowing
  65.   for a high degree of customization.
  66.  
  67.   Hundreds of builtin and user-defined functions are supplied for
  68.   manipulating strings, files, text buffers, cursors, windows, and a
  69.   large variety of other internal editor structures and features.
  70.  
  71.   AML also has powerful event-handling and object-oriented capabilities.
  72.   Functions can be defined which respond to external, internal, and user
  73.   defined events. Functions and variables can be encapsulated into
  74.   objects, and objects can organized into object hierarchies with
  75.   inheritance and multiple inheritance. Inheritance hierarchies can also
  76.   be dynamically altered within a macro.
  77.  
  78.   To simplify macro development, the editor is also configured to
  79.   provide compilation support for its own macro language. Macro source
  80.   code can be compiled and executed within the editor. If compilation
  81.   errors are found, the cursor is automatically moved to the appropriate
  82.   location in the source code for corrections.
  83.  
  84.  
  85.   The Syntax
  86.   ──────────
  87.   The macro language syntax includes a rich assortment of statements,
  88.   operators, and functions which can be combined to form very simple or
  89.   very complex expressions.
  90.  
  91.   In designing the macro language syntax, every effort was made to
  92.   provide an attractive interface to the editor which is both powerful
  93.   and easy-to-use. Those who are already familiar with other programming
  94.   languages will find the syntax of AML similar to BASIC or Pascal, but
  95.   with a simpler function call syntax.
  96.  
  97.   AML is also a 'typeless' language. The user need not be concerned with
  98.   conversions from string to numeric data, or vice versa, and variable
  99.   declarations are usually not required.
  100.  
  101.  
  102.   Identifiers
  103.   ───────────
  104.   Identifiers are user-defined names which denote variables and
  105.   functions. Valid identifiers may be composed of letters (a-z and A-Z),
  106.   numeric digits (0-9), underscores (_), question marks (?), and the
  107.   character (#). Identifiers cannot begin with a numeric character, and
  108.   are always case sensitive. For example:
  109.  
  110.   These identifiers are valid:
  111.     abc
  112.     variable13
  113.     _done?
  114.  
  115.   These identifiers are not valid:
  116.     12twelve          // identifiers may not start with numeric digit
  117.     bad variable      // identifiers may not include spaces
  118.     variable!         // the '!' character may not be used
  119.  
  120.  
  121.   Reserved Words
  122.   ──────────────
  123.   The following reserved words are used by the macro language for
  124.   keywords and statements and cannot be used as identifiers for
  125.   user-defined variables or functions:
  126.  
  127.     and        elseif     item       not        set        then  
  128.     break      end        key        object     setobj     until 
  129.     case       forward    keyword    or         setx       var   
  130.     databuf    function   loop       otherwise  setxfun    when  
  131.     define     if         menu       ref        setxobj    while 
  132.     do         if?        menubar    repeat     shl              
  133.     else       include    mod        return     shr              
  134.  
  135.   Unlike the identifiers used for variables and functions, reserved
  136.   words may be entered in mixed case.
  137.  
  138.  
  139.   Strings
  140.   ───────
  141.   A string is a contiguous sequence of characters, up to a maximum
  142.   length of 16000 characters. String constants must be enclosed in
  143.   either single quotes (') or double quotes (") and the starting quote
  144.   character must match the ending quote character. For example:
  145.  
  146.     "This is valid string"
  147.     'This is also a valid string'
  148.     "This is 'Ok'"
  149.     'This is "Ok" too'
  150.  
  151.     "This is not a string'
  152.        // quotes don't match
  153.  
  154.   A string with no characters is referred to as 'the null string':
  155.  
  156.     ''        // the null string
  157.     ""        // the null string
  158.  
  159.   The backslash character (\) is used to indicate that the next
  160.   character in the string is to be interpreted literally. It may be used
  161.   to enclose quote characters (and the literal character itself) in the
  162.   string. For example:
  163.  
  164.     '\''      // one single quote
  165.     "\"\"'"   // two double quotes and a single quote
  166.  
  167.   If the backslash character (\) is used in a string, it must be
  168.   preceded by another backslash character:
  169.  
  170.     '\\\\'              // a string containing two backslash characters
  171.     "C:\\TXT\\ABC.TXT"  // a fully qualified filename
  172.  
  173.  
  174.   Numbers
  175.   ───────
  176.   The macro language supports both decimal and hexadecimal integer
  177.   constants. A decimal constant is a contiguous sequence of numeric
  178.   digits. A hexadecimal constant is contiguous sequence of numeric
  179.   digits or the letters A through F followed by the letter 'h' (the
  180.   characters A through F and 'h' may be in mixed case). Both decimal and
  181.   hexadecimal constants must begin with a numeric digit. For example:
  182.  
  183.     2   72   1234567     // valid decimal numbers
  184.     0h  20h  0Dh  0ffH   // valid hexadecimal numbers
  185.  
  186.     ffh                  // invalid - must begin with a numeric digit
  187.  
  188.   All numbers must be within the range -2,147,483,648 to 2,147,483,647
  189.   and must be integers.
  190.  
  191.  
  192.   Spaces
  193.   ──────
  194.   To improve readability, spaces and lines many be inserted anywhere
  195.   within your macro source code, as long as they are not inserted within
  196.   reserved words, identifiers, multi-character operators, strings, or
  197.   numbers. For example:
  198.  
  199.     a=2 b="a is two" if a==2 then say b end 
  200.  
  201.   could be rewritten as:
  202.  
  203.     a = 2
  204.     b = "a is two"
  205.  
  206.     if a == 2 then 
  207.       say b
  208.     end 
  209.  
  210.  
  211.   Comments
  212.   ────────
  213.   Comments can make your source code much more descriptive and readable.
  214.   AML supports both single-line and multi-line comments.
  215.  
  216.   To place a comment at the end of a single line, use the single-line
  217.   comment delimiter '//'. In a single line comment, any characters
  218.   located between the delimiter '//' and the end of the line will be
  219.   ignored. For example:
  220.  
  221.     x = 2        // this is a single line comment
  222.  
  223.     // this is another single line comment
  224.     y = 3
  225.  
  226.   Multi-line comments can span any number of lines. For multi-line
  227.   comments, any characters located between the comment delimiters '/*'
  228.   and '*/' are ignored. For example:
  229.  
  230.     x = 2  /* this is multi-line comment */  y = 3
  231.  
  232.     /* this is
  233.        another
  234.        multi-line
  235.        comment */
  236.     y = 3
  237.  
  238.   Multi-line comments cannot be nested.
  239.  
  240.  
  241.   Variables
  242.   ─────────
  243.   A variable is an identifier which is associated with a value that can
  244.   be changed during execution. Since AML is typeless, variables do not
  245.   need to be defined with data types such as 'numeric', 'character', or
  246.   'string'. The macro language compiler and interpreter will
  247.   automatically handle these data types internally, based on the usage
  248.   of the variable.
  249.  
  250.   Variables fall into three categories:
  251.  
  252.   Local variables:
  253.     Local variables are defined only within the scope of a function
  254.     definition and only have values while the function is executing.
  255.     Local variables can only be referenced after they are defined and
  256.     only from within the function in which they are defined. For
  257.     example:
  258.                         // variable 'a' is not defined here
  259.       function xyz
  260.         a = 1           // variable 'a' is local to function 'xyz'
  261.       end 
  262.                         // variable 'a' is not defined here
  263.  
  264.   Global variables:
  265.     Global variables are defined outside the scope of any function
  266.     definition and only have values while the macro file in which they
  267.     are contained is executing. Global variables can only be referenced
  268.     after they are defined and only from within the macro source file in
  269.     which they are defined.
  270.  
  271.     Global variables can be referenced from inside or outside the scope
  272.     of a function definition. For example:
  273.  
  274.       g = 2             // 'g' is a global variable
  275.       function xyz
  276.         a = g           // 'g' is defined here, 'a' is local
  277.       end 
  278.       g = 3             // 'g' is defined here
  279.  
  280.     If a reference is made to a variable from within a function and the
  281.     variable name refers to both a local and a global variable, then the
  282.     local variable always takes precedence.
  283.  
  284.   Object variables:
  285.     Object variables are defined as they are used from any location
  286.     within a macro. When an object variable is assigned a value, it
  287.     continues to hold the value until it is assigned a new value, or the
  288.     object in which it is contained is destroyed (see 'Objects').
  289.  
  290.     Object variables which are assigned a value in one macro file can be
  291.     referenced in another macro file. In this sense, object variables
  292.     are more persistent and have an even larger scope than global
  293.     variables. Object variables can be referenced from any location
  294.     within a macro and must usually be prefixed with an underscore
  295.     character when referenced. For example:
  296.  
  297.       _abc = 2          // 'abc' is an object variable
  298.       function xyz
  299.         a = _abc        // 'abc' is defined here, 'a' is local
  300.       end 
  301.       _abc = 3          // 'abc' is defined here
  302.  
  303.  
  304.   The Assignment Statement
  305.   ────────────────────────
  306.   The assignment statement is used to change the value of a variable.
  307.   Assignment statements use the following form:
  308.  
  309.     variable_name = expression
  310.  
  311.   where the variable 'variable_name' is assigned the value of
  312.   'expression'. 'expression' may be a simple or complex macro language
  313.   expression composed of numbers, strings, other variables, other
  314.   expressions, function calls, or even other statements.
  315.  
  316.   A few simple examples of the assignment statement are:
  317.  
  318.     x = 2                        // sets the variable x to 2
  319.     x = x + 3                    // sets the variable x to 5
  320.     fruit = 'apple'              // sets the variable fruit to 'apple'
  321.     fruits = fruit + " orange"   // sets the variable fruits to
  322.                                  //    'apple orange'
  323.  
  324.   Object variables can also be assigned values by using the 'set'
  325.   statement. For example, the following two statements are equivalent:
  326.  
  327.     _count = 1     // set object variable 'count' to 1
  328.     set count 1    // set object variable 'count' to 1
  329.  
  330.   Note that the underscore (_) character is not required when an object
  331.   variable is referenced in the first part of the 'set' statement.
  332.  
  333.  
  334.   Variable Declarations
  335.   ─────────────────────
  336.   In most cases, variables are automatically declared the first time
  337.   they are assigned a value, and variable declarations are not required.
  338.   For example:
  339.  
  340.     function abc
  341.       a = 1                // local variable, declaration not required
  342.       say a                // displays '1'
  343.     end 
  344.  
  345.     xyz = 'Hello there!'   // global variable, declaration not required
  346.     say xyz                // displays 'Hello there!'
  347.  
  348.   However, if a local or global variable is referenced before it is
  349.   assigned a value, then it must first be declared with the 'var'
  350.   keyword. The 'var' keyword defines the identifier which follows it as
  351.   a variable name and initializes the value of the new variable to the
  352.   null string. For example:
  353.  
  354.     var  xyz                   // global variable 'xyz' is declared
  355.     say  xyz                   // displays nothing (the null string)
  356.  
  357.     function 
  358.       var a                    // local variable 'a' is declared
  359.       repeat 
  360.         a = a + 1              // 'a' is referenced before assigned
  361.       until a == 10
  362.     end 
  363.  
  364.   Object variables do not need to be declared. Since references to an
  365.   object variable must be preceded by an underscore character (_), the
  366.   compiler automatically recognizes object variables. If an object
  367.   variable is referenced and has not yet been assigned a value, the
  368.   value of the object variable is the null string. For example:
  369.  
  370.     say _objectvar             // displays nothing (the null string)
  371.  
  372.     _objectvar = 12
  373.     say _objectvar             // displays 12
  374.  
  375.  
  376.   Conversions
  377.   ───────────
  378.   Since the macro language is typeless, explicit conversion between data
  379.   types is not required. If a string is specified where a number is
  380.   expected, it is converted to a number as it is used. Similarly, if a
  381.   number is specified where a string is expected, it is converted to a
  382.   string. For example:
  383.  
  384.     x = "12" + "34"       // x is '46'
  385.     x = 12 + "abc"        // x is '12abc'
  386.  
  387.  
  388.   Expressions
  389.   ───────────
  390.   Expressions are simple or complex groups of numbers, strings,
  391.   variables, function calls, statements, or other expressions joined
  392.   together by zero or more macro language 'operators'. These are just a
  393.   few examples of simple expressions:
  394.  
  395.     1
  396.     abc
  397.     x / 4
  398.     "apples " + "oranges"
  399.     x and y
  400.     getlines - getrow
  401.  
  402.   Expressions may be enclosed in parentheses (called 'subexpressions')
  403.   and joined by operators to form more complex expressions:
  404.  
  405.     (x + y) / 2
  406.     ((a + b) * (b + c)) shl (c - d)
  407.     (a or b) and ((not c) or d)
  408.  
  409.   The evaluation of expressions generally proceeds from left to right,
  410.   but is also based on the priority of the operators within the
  411.   expression, or the 'operator precedence'. Operators with higher
  412.   precedence are evaluated before operators with lower precedence. For
  413.   example, in the expression:
  414.  
  415.     x - y * 5
  416.  
  417.   'y * 5' is evaluated first and then subtracted from 'x', since the
  418.   multiplication operator '*' has a higher precedence than the
  419.   subtraction operator '-'. Parentheses may be used to force the
  420.   expression to be evaluated with a user-defined priority. For example:
  421.  
  422.     (x - y) * 5
  423.  
  424.   In the above example, 'x - y' is evaluated first, and then multiplied
  425.   by '5'.
  426.  
  427.   Note that while the value of an expression is always based on
  428.   parentheses and operator precedence, the actual order in time in which
  429.   elements of the expression are evaluated is not defined (the 'and' and
  430.   'or' operators are exceptions - see 'Logical Operators') . For
  431.   example:
  432.  
  433.     (funA 1) + (funB 2) * (funC 3)
  434.  
  435.   In the expression above, you may not assume that the function 'funC'
  436.   is called before the function 'funA'.
  437.  
  438.  
  439.   True and False
  440.   ──────────────
  441.   Several macro language operators and statements test whether an
  442.   expression is TRUE or FALSE. An expression is FALSE if it is equal to
  443.   zero or the null string. For any other values, the expression is TRUE.
  444.   For example:
  445.  
  446.     x = 4   // x is TRUE
  447.     x + 3   // value is TRUE
  448.     x - 4   // value is FALSE
  449.     x = ''  // x is FALSE
  450.  
  451.  
  452.   Arithmetic Operators
  453.   ────────────────────
  454.   Arithmetic operators are used to perform simple integer arithmetic on
  455.   numbers within expressions. The result of any arithmetic expression is
  456.   always an integer in the range of -2,147,483,648 to 2,147,483,647. The
  457.   arithmetic operators are:
  458.  
  459.     *    multiplication
  460.     /    division
  461.     mod  modulation
  462.     +    addition
  463.     -    subtraction (or unary negation)
  464.  
  465.   The division and mod operators perform an integer division. The
  466.   division operator truncates any fractional result. The mod operator
  467.   returns an integer remainder.
  468.  
  469.   Addition and subtraction have a lower precedence than multiplication
  470.   and division. Unary negation has a higher precedence than than all the
  471.   other arithmetic operators (and all other operators except the
  472.   parentheses and substring operators).
  473.  
  474.   Examples:
  475.  
  476.     y = 5
  477.     x = (6 + y * 3) / 2    // x is 10
  478.     z = x mod 3            // z is 1
  479.  
  480.  
  481.   Relational Operators
  482.   ────────────────────
  483.   Relational operators are used to compare two expressions. The result
  484.   of evaluating a relational operator is always either TRUE (1) or FALSE
  485.   (the null string). Relational operators have a lower precedence than
  486.   arithmetic operators. The relational operators are:
  487.  
  488.     <    less than
  489.     <=   less than or equal to
  490.     >    greater than
  491.     >=   greater than or equal to
  492.     ==   equal to
  493.     <>   not equal to
  494.  
  495.   Note that relational operators can be used to compare both numbers and
  496.   strings. Strings are compared by testing the ASCII values of each
  497.   character in the string from left to right (a case sensitive
  498.   comparison).
  499.  
  500.   Examples:
  501.  
  502.     // numeric comparisons
  503.     a = 4  b = 5
  504.     a < b   a <> b  a == b - 1  // these expressions are TRUE
  505.     a > b   a == b              // these expressions are FALSE
  506.     x = a < b                   // x is assigned a value of '1'
  507.     x = a == b                  // x is assigned the null string
  508.  
  509.     // string comparisons
  510.     a = "abc"  b = "xyz"
  511.     a < b   a <> b              // these expressions are TRUE
  512.     a > b   a == b              // these expressions are FALSE
  513.     x = a < b                   // x is assigned a value of '1'
  514.     x = a == b                  // x is assigned the null string
  515.  
  516.  
  517.   String Operators
  518.   ────────────────
  519.   String operators are used to perform string concatenation and
  520.   substring operations on character strings. The result of evaluating a
  521.   string expression is always a character string. The string operators
  522.   are:
  523.  
  524.     +                concatenation
  525.     [ expr ]         one-character substring
  526.     [ expr : expr ]  multi-character substring
  527.  
  528.   The concatenation operator '+' is used to join two or more strings
  529.   together. For example:
  530.  
  531.     a = "apples"
  532.     b = "oranges"
  533.     x = a + " and " + b        // x is 'apples and oranges'
  534.     x = 4 + ' ' + a            // x is '4 apples'
  535.  
  536.   Since the concatenation operator '+' is identical to the addition
  537.   operator '+', two numeric strings cannot be concatenated with '+'. In
  538.   this case, addition takes precedence (AML is a typeless language):
  539.  
  540.     x = "13" + "12"            // x is 25
  541.     x = "13" + 4               // x is 17
  542.  
  543.   To concatenate two or more numeric strings, use the 'concat' builtin
  544.   function:
  545.  
  546.     x = concat "13" "12"       // x is "1312"
  547.  
  548.   The substring operator [] is used to return a portion of a string. If
  549.   only one numeric operand is specified, then the substring operator
  550.   references a one-character substring at the position in the string
  551.   specified by the operand. For example:
  552.  
  553.     a = "apples"
  554.     b = "oranges"
  555.     x = a [1]                  // x is 'a'
  556.     x = b [5]                  // x is 'g'
  557.     n = 4
  558.     x = b [n + 2]              // x is 'e'
  559.  
  560.   Specifying a position of zero references the last character in the
  561.   string:
  562.  
  563.     a = "apples"
  564.     x = a [0]                  // x is 's'
  565.  
  566.   If two numeric operands are specified separated by a colon, then the
  567.   substring operator references a multi-character substring at the
  568.   position in the string specified by the first operand for the length
  569.   specified by the second operand. For example:
  570.  
  571.     a = "apples"
  572.     b = "oranges"
  573.     x = a [1:3]                // x is 'app'
  574.     x = b [2:5]                // x is 'range'
  575.     n = 3
  576.     x = b [n - 1 : n + 2]      // x is 'range'
  577.  
  578.   Specifying a length of zero returns the remainder of the string,
  579.   starting at the specified position:
  580.  
  581.     b = "oranges"
  582.     x = b [2:0]                // x is 'ranges'
  583.  
  584.   Note that the [] operator is not limited to variables. The [] operator
  585.   can also be used with constants, numbers, expressions, and function
  586.   calls. For example:
  587.  
  588.     i = 2
  589.     x = "oranges" [i : 5]              // x is 'range'
  590.     x = 26381 [3 : i]                  // x is '38'
  591.     x = ('oranges' + 'apples') [7:3]   // x is 'sap'
  592.     x = getlines [0]                   // x is the last digit of the
  593.                                        //   total number of lines in the
  594.                                        //   current buffer
  595.  
  596.  
  597.   Logical Operators
  598.   ─────────────────
  599.   Logical operators test whether or not expressions are TRUE or FALSE.
  600.   The result of evaluating a logical operator is also either TRUE (1) or
  601.   FALSE (the null string). The logical operators are:
  602.  
  603.     and  - tests if two expressions are TRUE
  604.     or   - tests if at least one of two expressions is TRUE
  605.     not  - tests if an expression is FALSE
  606.  
  607.   Examples:
  608.  
  609.     a = 4  b = 5
  610.     a and b                       // value is TRUE
  611.     a - 4 and b                   // value is FALSE
  612.     a - 4 or b                    // value is TRUE
  613.     a == 5 or b == 4              // value is FALSE
  614.     not a                         // value is FALSE
  615.     not (b - a - 1)               // value is TRUE
  616.  
  617.   The 'and' and 'or' operators have a lower precedence than the
  618.   arithmetic and relational operators. For example:
  619.  
  620.     a == 4 and a == b - 1         // is equivalent to..
  621.     (a == 4) and (a == (b - 1))
  622.  
  623.   The 'not' operator has a higher precedence than both the arithmetic
  624.   and relational operators. For example:
  625.  
  626.     b = 3;
  627.     a = not b + 1       // a is 1
  628.  
  629.   Note that the 'and' and 'or' operators do not always evaluate all the
  630.   expressions they compare. Once the value of the logical expression is
  631.   known, no further evaluation occurs. For example:
  632.  
  633.     (funA 1) or (funB 2)
  634.  
  635.   In the example above, if 'funA 1' is TRUE, the or-expression is TRUE
  636.   and the function 'funB' is not called. Similarly:
  637.  
  638.     (funA 1) and (funB 2)
  639.  
  640.   In the above example, if 'funA 1' is FALSE, the and-expression is
  641.   FALSE and the function 'funB' is not called.
  642.  
  643.  
  644.   Bitwise Operators
  645.   ─────────────────
  646.   The bitwise operators can be used to manipulate or test individual
  647.   bits in numeric expressions. Bitwise operators have a higher
  648.   precedence than the 'and' and 'or' logical operators and a lower
  649.   precedence than the relational operators. The bitwise operators are:
  650.  
  651.     shl   shift bits left
  652.     shr   shift bits right
  653.     &     bitwise and
  654.     |     bitwise or
  655.     ^     bitwise exclusive-or
  656.  
  657.   Examples:
  658.  
  659.     a = 3  b = 6     // a = 00000011 in binary, b = 00000110 in binary
  660.     a shl 2          // value is 00001100 in binary, or 12 in decimal
  661.     b shl 1          // value is 00000011 in binary, or 3 in decimal
  662.     a & b            // value is 00000010 in binary, or 2 in decimal
  663.     a | b            // value is 00000111 in binary, or 7 in decimal
  664.     a ^ b            // value is 00000101 in binary, or 5 in decimal
  665.     a & 0fh          // value is TRUE (the 5th bit is '1' in 'a')
  666.     a = a | 4        // turns on the 3rd bit in 'a', a = 7
  667.     a = a ^ 8        // toggles the 4th bit in 'a', a = 11
  668.  
  669.  
  670.   Operator Precedence
  671.   ───────────────────
  672.   The following table shows the precedence of all macro language
  673.   operators (lower level numbers have higher precedence):
  674.  
  675.   Level    Operator     Description
  676.   ─────    ────────     ───────────
  677.    1       ()           Subexpressions, function call
  678.            []           Substring
  679.    2       +            Unary plus
  680.            -            Unary minus
  681.            not          Logical negation
  682.    3       *            Multiplication
  683.            /            Division
  684.            mod          Modulation
  685.    4       +            Addition
  686.            -            Subtraction
  687.    5       shl          Bitwise shift left
  688.            shr          Bitwise shift right
  689.    6       <            Less than
  690.            >            Greater than
  691.            <=           Less than or equal to
  692.            >=           Greater than or equal to
  693.    7       ==           Equal to
  694.            <>           Not equal to
  695.    8       &            Bitwise AND
  696.    9       ^            Bitwise XOR
  697.   10       |            Bitwise OR
  698.   11       and          Logical AND
  699.   12       or           Logical OR
  700.   13       =            Assignment
  701.  
  702.  
  703.   Control Statements
  704.   ──────────────────
  705.   Macro language expressions and statements are normally executed
  706.   sequentially from left to right and top to bottom. Control statements
  707.   provide ways to alter this control flow. The following control
  708.   statements are available:
  709.  
  710.     if elseif else end 
  711.     if? 
  712.     case when otherwise end 
  713.     while do end 
  714.     repeat until 
  715.     loop end 
  716.     break 
  717.     return 
  718.  
  719.   The 'if', 'if?', and 'case' statements can also be used within
  720.   expressions.
  721.  
  722.  
  723.   If and If? Statements
  724.   ─────────────────────
  725.   The 'if' and 'if?' statements can be used to conditionally execute
  726.   macro code based on whether or not an expression is TRUE or FALSE.
  727.  
  728.   The format of the 'if' statement is:
  729.  
  730.     if condition then 
  731.       expressions
  732.     elseif condition then 
  733.       expressions
  734.     elseif condition then 
  735.       .
  736.       .
  737.     else 
  738.       expressions
  739.     end 
  740.  
  741.   Both the 'elseif' and 'else' clauses are optional. The 'elseif' clause
  742.   may be specified any number of times, but the 'else' clause can only
  743.   be specified once. 'if' statements may also be nested.
  744.  
  745.   The 'if' statement evaluates each 'if' or 'elseif' condition
  746.   expression until one condition evaluates to TRUE. If a TRUE condition
  747.   is found, the expressions associated with that condition are
  748.   evaluated. If no conditions are TRUE and an 'else' clause is
  749.   specified, then the expressions within the 'else' clause are
  750.   evaluated. For example:
  751.  
  752.     a = 4
  753.     if a == 3 then 
  754.       say 'a is 3'
  755.     elseif a == 4 then 
  756.       say 'a is 4'                     // displays 'a is 4'
  757.     else 
  758.       say 'a is something else'
  759.     end 
  760.  
  761.   Note that 'if' statements may also be used as expressions. In this
  762.   case, the value of the 'if' statement is the value of the last
  763.   expression evaluated within the 'if' statement. For example:
  764.  
  765.     a = 4
  766.     say  a + if a == 6 then   // displays '15'
  767.                10
  768.              else 
  769.                11
  770.              end 
  771.  
  772.   The 'if?' statement is a shorthand version of the 'if' statement. The
  773.   format of the 'if?' statement is:
  774.  
  775.     if? condition then_expression else_expression
  776.  
  777.   where 'else_expression' is optional.
  778.  
  779.   The 'if?' statement evaluates the expression 'condition'. If the
  780.   condition is TRUE, 'then_expression' is evaluated, otherwise
  781.   'else_expression' is evaluated.
  782.  
  783.   The 'if?' statement is primarily intended for use within expressions,
  784.   where it may be less cumbersome to use than the full 'if' statement.
  785.   The previous example could be rewritten as:
  786.  
  787.     a = 4
  788.     say  a + ( if? a == 6 10 11 )
  789.  
  790.  
  791.   The Case Statement
  792.   ──────────────────
  793.   The 'case' statement can be used as a more convenient way to write a
  794.   large 'if' statement. It compares the value of an expression to many
  795.   other expressions.
  796.  
  797.   The format of the case statement is:
  798.  
  799.     case expression
  800.       when when_expression
  801.         expressions
  802.       when when_expression
  803.         expressions
  804.       .
  805.       .
  806.       otherwise 
  807.         expressions
  808.     end 
  809.  
  810.   Both the 'when' and 'otherwise' clauses are optional. The 'when'
  811.   clause may be specified any number of times, but the 'otherwise'
  812.   clause can only be specified once. 'case' statements may be nested.
  813.  
  814.   The 'case' statement compares the value of the case expression to the
  815.   value of each when_expression until they equal. If they are equal, the
  816.   expressions associated with the matching 'when' clause are evaluated.
  817.   If no 'when' clauses are equal to the case expression, then the
  818.   expressions within the 'otherwise' clause are evaluated. 'when'
  819.   expressions can also test for multiple values by separating them with
  820.   commas. For example:
  821.  
  822.     a = 4
  823.     case a
  824.       when 3
  825.         say 'a is 3'
  826.       when 1, 2, 4
  827.         say 'a is 1, 2, or 4'          // displays 'a is 1, 2, or 4'
  828.       otherwise 
  829.         say 'a is something else'
  830.     end 
  831.  
  832.   Like 'if' statements, 'case' statements may also be used as
  833.   expressions. The value of the 'case' statement is the value of the
  834.   last expression evaluated within the 'case' statement. For example:
  835.  
  836.     x = 4
  837.     x = case x
  838.           when 1  'one'
  839.           when 4  'four'
  840.           when 7  'seven'
  841.           otherwise 
  842.             'something else'
  843.         end 
  844.     say x                              // displays 'four'
  845.  
  846.  
  847.   Iterative Statements
  848.   ────────────────────
  849.   Iterative statements evaluate a series of expressions repeatedly,
  850.   usually while a condition is TRUE or until a condition is TRUE. There
  851.   are three iterative statements: while do/end, repeat/until, and
  852.   loop/end.
  853.  
  854.   The 'while' statement evaluates a series of expressions repeatedly
  855.   while another expression is TRUE. The format of the 'while' statement
  856.   is:
  857.  
  858.     while while_expression do 
  859.       expressions
  860.     end 
  861.  
  862.   'while_expression' is always evaluated before the first iteration of
  863.   the loop. For example:
  864.  
  865.     x = 10
  866.     while x do 
  867.       x = x - 1             // count downward to zero
  868.     end 
  869.  
  870.  
  871.   The 'repeat' statement evaluates a series of expressions repeatedly
  872.   until another expression is TRUE. The format of the 'repeat' statement
  873.   is:
  874.  
  875.     repeat 
  876.       expressions
  877.     until until_expression
  878.  
  879.   'until_expression' is evaluated after the first iteration of the loop.
  880.   For example:
  881.  
  882.     x = 1
  883.     repeat 
  884.       x = x + 1             // count upward to 10
  885.     until x == 10
  886.  
  887.  
  888.   The 'loop' statement evaluates a series of expressions until a
  889.   'break', or 'return' statement is executed. It is important that one
  890.   of these statements is executed, otherwise the 'loop' statement will
  891.   repeat forever. The format of the 'loop' statement is:
  892.  
  893.     loop 
  894.       expressions
  895.     end 
  896.  
  897.   Example:
  898.  
  899.     loop 
  900.       case getkey                    // wait for key
  901.         when <esc>                   // <esc> exits the loop
  902.           break 
  903.         otherwise 
  904.           say "you didn't press <esc>"
  905.       end 
  906.     end 
  907.  
  908.   Note that the <ctrl break> key can be used to force an immediate exit
  909.   from any of the above loops, which may may be helpful when debugging
  910.   macros. However, <ctrl break> should be used with care, since it may
  911.   leave the editor in an unstable state.
  912.  
  913.  
  914.   Other Control Statements
  915.   ────────────────────────
  916.   Two other control statements are provided: the 'break' statement, and
  917.   the 'return' statement.
  918.  
  919.   The 'break' statement immediately forces an unconditional exit from
  920.   any 'while', 'repeat', or 'loop' statement in which it is located.
  921.  
  922.   The 'return' statement immediately forces an unconditional exit from
  923.   the macro or macro function in which it is located. The 'return'
  924.   statement can also be used to return a value to a calling function by
  925.   specifying an expression after the 'return' keyword. For example:
  926.  
  927.     function abc
  928.       return                 // returns the null string to the
  929.     end                      //   calling function
  930.  
  931.     function xyz
  932.       a = 4
  933.       b = 5
  934.       return a + b           // returns '9' to the calling function
  935.     end 
  936.  
  937.  
  938.   Function Calls
  939.   ──────────────
  940.   Perhaps the most common macro language statement is the function call
  941.   statement. The function call statement transfers control to a
  942.   function, passing optional user-defined arguments. When the function
  943.   returns, execution resumes at the statement after the function call.
  944.   The format of the function call statement is:
  945.  
  946.     function_name  argument1 argument2 argument3 ...
  947.  
  948.   'function_name' may be a builtin function or a user-defined function.
  949.   Any number of user-defined arguments (depending on available stack
  950.   space) can be passed to a function. Arguments are always evaluated
  951.   from left to right. For example:
  952.  
  953.     say "Just one argument"   // one argument
  954.     beep 400 x + 500          // two arguments
  955.     delline                   // no arguments
  956.  
  957.   Since every function returns a value, function calls may be used
  958.   anywhere in an expression. For example:
  959.  
  960.     x = getlines
  961.       // call 'getlines' and place the result in variable x
  962.  
  963.     y = (pos 'i' astring) - 1
  964.       // call pos with arguments 'i' and astring, subtract 1 from the
  965.       //   result, and place the new result in variable y
  966.  
  967.     // beep if the functions 'up' and 'getlinelen' both return TRUE
  968.     if (up 2) and getlinelen then 
  969.       beep 400 500
  970.     end 
  971.  
  972.   If a function call with one or more arguments is used within an
  973.   expression, the entire function call should be enclosed in
  974.   parentheses, otherwise operators in the expression may assume the
  975.   function arguments as their operands. For example:
  976.  
  977.     str = "oranges"
  978.  
  979.     y = (pos 'g' str) + 1     // y is 6
  980.     y = pos 'g' str + 1       // y is 5
  981.     y = x + getrow + 1
  982.  
  983.   In the first example above, the function 'pos' is called with the
  984.   arguments 'g' and the value of 'str', and 1 is added to the result. In
  985.   the second example, 1 is concatenated to the value of 'str' and the
  986.   result becomes the second argument to the function 'pos'. In the third
  987.   example, there is no ambiguity and the function call 'getrow' does not
  988.   need to be enclosed in parentheses.
  989.  
  990.   If an argument in a function call is also a function call, then the
  991.   argument must be enclosed in parentheses. For example:
  992.  
  993.     markline 1 (getlines "abc")
  994.  
  995.   In the example above, the function call 'getlines "abc"' is the second
  996.   argument to the function call 'markline'. If the function call
  997.   'getlines "abc"' was not enclosed in parentheses, then it would become
  998.   a second statement, and the first statement would become 'markline 1'.
  999.  
  1000.   If an argument in a function call is an expression separated by
  1001.   operators or is not itself a function call, then the argument does not
  1002.   need to be enclosed in parentheses. For example:
  1003.  
  1004.     markline  y  b                       // no parens needed
  1005.     markline  y + 1   a + b - 1          // no parens needed
  1006.     markline  y + getrow + 1 (getlines)  // 1st arg doesn't need parens
  1007.     markline  (getrow)  y + getlines     // 2nd arg doesn't need parens
  1008.  
  1009.  
  1010.   Function Definitions
  1011.   ────────────────────
  1012.   The editor has hundreds of builtin functions such as 'markline' or
  1013.   'beep' which are predefined. Builtin functions may be used anywhere
  1014.   without any declarations or definitions.
  1015.  
  1016.   To define your own functions, you must use the 'function' statement.
  1017.   The 'function' statement allows you to organize chunks of macro code
  1018.   into a package which can referred to later with a function call, thus
  1019.   allowing you to reuse existing code. The format of the 'function'
  1020.   statement is:
  1021.  
  1022.     function functionname (arg1 arg2 ...)
  1023.       .
  1024.       <macro code>
  1025.       .
  1026.     end 
  1027.  
  1028.   The argument list (arg1 arg2 ...) is optional. Note that 'function'
  1029.   statements cannot be nested.
  1030.  
  1031.   The 'function' statement defines the function 'functionname' and
  1032.   associates it with the <macro code> contained within the body of the
  1033.   function. For example:
  1034.  
  1035.     // define the function 'abc'
  1036.     function abc
  1037.       say "Hello World!"
  1038.     end 
  1039.  
  1040.     // call function 'abc' (displays 'Hello World!')
  1041.     abc
  1042.  
  1043.   Functions may also be called before they are defined by using the
  1044.   'forward' keyword. The 'forward' keyword informs the compiler that the
  1045.   name which follows it is to be treated as a function name. For
  1046.   example:
  1047.  
  1048.     forward abc
  1049.  
  1050.     // call 'abc'
  1051.     abc
  1052.  
  1053.     // define the function 'abc'
  1054.     function abc
  1055.       say "Hello World!"
  1056.     end 
  1057.  
  1058.   The 'forward' keyword must also be used to declare functions which are
  1059.   called in the current macro source file, but which are actually
  1060.   defined in external macro language object modules (.X files). The
  1061.   editor library functions in LIB.X are examples of such functions.
  1062.   The 'forward' declarations for library functions can be found in
  1063.   DEFINE.AML.
  1064.  
  1065.  
  1066.   Function Types
  1067.   ──────────────
  1068.   Although the macro language compiler views functions as being either
  1069.   'builtin' or 'user-defined', three types of editor functions are
  1070.   referred to in this document and are defined briefly here:
  1071.  
  1072.     Builtin functions: these are pre-defined functions which are native
  1073.       to the macro language.
  1074.  
  1075.     Library functions: these are pre-compiled user-defined functions
  1076.       contained in LIB.X. No source code is provided for these
  1077.       functions.
  1078.  
  1079.     Extension functions: these are user-defined functions contained in
  1080.       EXT.AML. Source code is provided for these functions.
  1081.  
  1082.   Builtin functions and Library functions are also documented in the AML
  1083.   Function Reference (FUNCTION.DOX).
  1084.  
  1085.  
  1086.   Passing Arguments to Functions
  1087.   ──────────────────────────────
  1088.   Arguments may be passed to user-defined functions and accessed as
  1089.   variables within the body of the function. Consider the format of the
  1090.   function statement:
  1091.  
  1092.     function  functionname  (arg1 arg2 ...)
  1093.       .
  1094.      <macro code>
  1095.       .
  1096.     end 
  1097.  
  1098.   The optional argument list (arg1 arg2 ...) assigns names to any
  1099.   variables which may be passed to the function during a function call.
  1100.   Note that the argument list does not define how many variables must be
  1101.   passed to the function - this is defined by a call to the function.
  1102.  
  1103.   If fewer arguments are passed to the function than are defined in the
  1104.   argument list, the extra variables will be equal to the null string on
  1105.   entry to the function. For example:
  1106.  
  1107.     // define function 'abc' with one argument
  1108.     function abc (message)
  1109.       if message then 
  1110.         say message
  1111.       else 
  1112.         say "No message!"
  1113.       end 
  1114.     end 
  1115.  
  1116.     // call 'abc' with no arguments (displays "No message!")
  1117.     abc
  1118.  
  1119.   If more arguments are passed to the function than are defined in the
  1120.   argument list, the extra arguments will not be accessible by name
  1121.   within the function. However, these arguments can still be accessed
  1122.   with the 'arg' builtin function. The 'arg' builtin function takes one
  1123.   argument: the position of the argument in the argument list. For
  1124.   example:
  1125.  
  1126.     // define function 'xyz' with 1 argument
  1127.     // (obtain the second argument with the 'arg' function)
  1128.     function xyz (message)
  1129.       say message + (arg 2)
  1130.     end 
  1131.  
  1132.     // call 'xyz' with 2 arguments (displays "Hello World!")
  1133.     xyz "Hello " "World!"
  1134.  
  1135.   If the 'arg' function is specified with no arguments (or the argument
  1136.   '0'), the number of arguments is returned. For example:
  1137.  
  1138.     // define the function 'countargs'
  1139.     function countargs
  1140.       say "The number of arguments is: " + (arg)
  1141.     end 
  1142.  
  1143.     // call 'xyz' (displays "The number of arguments is: 4")
  1144.     countargs 5 7 32 3
  1145.  
  1146.  
  1147.   Passing Variables by Reference
  1148.   ─────────────────────────────
  1149.   Variables can also be passed 'by reference' to a function. When a
  1150.   variable is passed by reference and the variable is modified in the
  1151.   called function, it is also modified where it was called. This can be
  1152.   used to return more than one value from a function.
  1153.  
  1154.   To pass variables 'by reference' to a function, use the 'ref' keyword
  1155.   before the variable in the function call (not in the argument list of
  1156.   the function definition). Only local and global variables may be
  1157.   passed by reference (object variables cannot be passed by reference).
  1158.   For example:
  1159.  
  1160.     // the 'modify' function changes the values of its arguments
  1161.     function modify (c d)
  1162.       c = 13
  1163.       d = 14
  1164.     end 
  1165.  
  1166.     function callmod
  1167.       a = 1
  1168.       b = 2
  1169.       modify  ref a  ref b         // pass 'a' and 'b' by reference
  1170.       say a + b                    // displays 27 (not 3)
  1171.     end 
  1172.  
  1173.  
  1174.   Function Return Values
  1175.   ──────────────────────
  1176.   All function calls in AML return a value, including calls to builtin
  1177.   functions and calls to user-defined functions. Builtin functions have
  1178.   predefined return values. User-defined functions can return values by
  1179.   default or by using the 'return' statement. Functions can also use
  1180.   variables passed by reference to return multiple values (see: Passing
  1181.   Variables by Reference).
  1182.  
  1183.   If no 'return' statement is included in the definition of a
  1184.   user-defined function, the function will return the value of the last
  1185.   expression evaluated in the function 'by default'. For example:
  1186.  
  1187.     // define the function 'datetime'
  1188.     function datetime (date)
  1189.       if date then 
  1190.         // the builtin function 'getdate' returns the current date
  1191.         getdate
  1192.       else 
  1193.         // the builtin function 'gettime' returns the current time
  1194.         gettime
  1195.       end 
  1196.     end 
  1197.  
  1198.     // call 'datetime' (displays the current date)
  1199.     say (datetime 1)
  1200.  
  1201.   The 'return' statement forces an immediate return from a function (or
  1202.   an external macro file), and returns a value. Any number of return
  1203.   statements can be specified. The value returned is the value of the
  1204.   expression following the return statement. If no expression follows
  1205.   the 'return' statement, then the null string is returned. For example:
  1206.  
  1207.     // define the function 'testvar'
  1208.     function testvar (variable)
  1209.       if variable == 'null' then 
  1210.         return 
  1211.       elseif variable then 
  1212.         return variable + 4
  1213.       else 
  1214.         return 'variable is null'
  1215.       end 
  1216.     end 
  1217.  
  1218.     say (testvar)           // displays 'variable is null'
  1219.     say (testvar 'null')    // displays nothing (the null string)
  1220.     say (testvar 5)         // displays '9'
  1221.  
  1222.  
  1223.   Objects
  1224.   ───────
  1225.   Using objects can help you to organize your macro code at an even
  1226.   higher level than functions.
  1227.  
  1228.   A macro language object is a user-defined collection of functions,
  1229.   object variables, and even other objects, which all work together to
  1230.   handle a complex task. In many ways, a macro language object is very
  1231.   much like a mini-database with function definitions and object
  1232.   variables as database records. Each object is identified by an object
  1233.   name.
  1234.  
  1235.   Most of the macro code base installed with the editor is organized
  1236.   into objects. For example, there are separate objects for edit
  1237.   windows, file manager windows, and prompt windows. The object 'edit'
  1238.   contains functions and variables for manipulating edit windows and
  1239.   processing edit window events. Likewise, the object 'fmgr' contains
  1240.   functions and variables for manipulating file manager windows and
  1241.   processing file manager window events.
  1242.  
  1243.  
  1244.   Object Definitions
  1245.   ──────────────────
  1246.   When the editor is initially started from the DOS command line, a
  1247.   default object named 'a' is automatically created. The object 'a'
  1248.   contains all the builtin editor functions and becomes the 'current'
  1249.   object immediately after the editor is started.
  1250.  
  1251.   The 'current' object is the object where macro code is currently being
  1252.   executed. It is also where all newly-defined functions and object
  1253.   variables are placed. For example:
  1254.  
  1255.     function xyz (message)
  1256.       say message
  1257.     end 
  1258.  
  1259.     _message = "Hello!"
  1260.     xyz _message
  1261.  
  1262.   If the above code is executed immediately upon starting the editor,
  1263.   the function 'xyz' and the object variable 'message' are both placed
  1264.   in the object 'a'.
  1265.  
  1266.   To create a new object or change the current object, use the 'object'
  1267.   statement. The format of the 'object' statement is:
  1268.  
  1269.     object  object_name  (parent1 parent2 ...)
  1270.  
  1271.   The object inheritance list (parent1 parent2 ...) is optional.
  1272.  
  1273.   The 'object' statement will create a new object if the specified
  1274.   object_name does exist. In either case, the specified object becomes
  1275.   the current object. For example:
  1276.  
  1277.     // create the new object 'hello'
  1278.     // ..and make it the current object
  1279.     object hello
  1280.  
  1281.       // add the function 'xyz' to object 'hello'
  1282.       function xyz (message)
  1283.         writestr message
  1284.       end 
  1285.  
  1286.     // create the new object 'goodbye'
  1287.     // ..and make it current object
  1288.     object goodbye
  1289.  
  1290.       // add object variable 'message' to object 'goodbye'
  1291.       _message = "Goodbye!"
  1292.  
  1293.     // now object 'hello' already exists,
  1294.     // ..so change the current object to 'hello'
  1295.     object  hello
  1296.  
  1297.       // add object variable 'message' to object 'hello'
  1298.       _message = "Hello!"
  1299.  
  1300.       // call the function 'xyz' previously defined in object 'hello'
  1301.       xyz _message
  1302.  
  1303.   Note that the 'object' statement is not terminated by the 'end'
  1304.   keyword.
  1305.  
  1306.  
  1307.   Object Inheritance
  1308.   ──────────────────
  1309.   An object can 'inherit' the functions and object variables of other
  1310.   objects by specifying other objects in the inheritance list of the
  1311.   'object' statement. When functions and variables are inherited, they
  1312.   can be called and referenced just as if they were contained in the
  1313.   original object.
  1314.  
  1315.   Consider the format of the 'object' statement:
  1316.  
  1317.     object  object_name  (parent1 parent2 ...)
  1318.  
  1319.   The optional object inheritance list (parent1 parent2 ...) specifies
  1320.   the objects from which object_name may inherit functions and object
  1321.   variables. The inheritance list is set regardless of whether or not
  1322.   the object 'object_name' existed previously.
  1323.  
  1324.   The objects 'parent1', 'parent2', etc. become the 'parent' objects of
  1325.   'object_name'. The object 'object_name' is said to be descended from
  1326.   'parent1', 'parent2' etc., since it inherits the characteristics
  1327.   (functions and variables) of these objects.
  1328.  
  1329.   Consider the following example:
  1330.  
  1331.     // create the new object 'parent'
  1332.     object parent
  1333.  
  1334.       // add the object variable _message to object 'parent'
  1335.       _message = "Hello"
  1336.  
  1337.       // add the function 'xyz' to object 'parent'
  1338.       function xyz (message)
  1339.         writestr message
  1340.       end 
  1341.  
  1342.     // create a new object named 'child' descended from object 'parent'
  1343.     object child (parent)
  1344.  
  1345.       // now call 'xyz' with the argument "Hello" (both the function
  1346.       // 'xyz' and the object variable 'message' are inherited from
  1347.       // the object 'parent')
  1348.       xyz _message
  1349.  
  1350.   Note that references to inherited functions and variables are
  1351.   completely transparent once the inheritance list has been set. In the
  1352.   example above, it appears that the function 'xyz' and the variable
  1353.   'message' actually reside in the object 'child'.
  1354.  
  1355.   Parent objects may also have inheritance lists. When a function or
  1356.   variable reference is made and the reference is not found in the
  1357.   current object, then the inheritance list hierarchy of the object is
  1358.   searched in a 'depth first' manner. This means that the first parent
  1359.   object in the inheritance list of the object is searched first, then
  1360.   the inheritance list of the first parent object, and so on. The second
  1361.   parent object is searched only when the entire inheritance hierarchy
  1362.   of the first parent object has been searched without resolving the
  1363.   reference.
  1364.  
  1365.   Note that builtin editor functions are always immediately accessible
  1366.   from within any object (inheritance lists are not searched).
  1367.  
  1368.   The builtin function 'objtype?' can be used to test the inheritance
  1369.   hierarchy or 'ancestry' of an object. For example:
  1370.  
  1371.     // tests if the current object is descended from the object 'edit'
  1372.     if objtype? "edit" then 
  1373.       .
  1374.       .
  1375.     end 
  1376.  
  1377.  
  1378.   Other Object Statements and Functions
  1379.   ─────────────────────────────────────
  1380.   There are several object statements which are useful for changing the
  1381.   value of an object variable. When using these statements, the
  1382.   underscore character (_) is not required when specifying the object
  1383.   variable to change.
  1384.  
  1385.   The 'set' statement changes the value of an object variable in the
  1386.   current object. Its effect is equivalent to the object variable
  1387.   assignment statement:
  1388.  
  1389.     set _variable 12
  1390.     set variable 12           // the underscore is not required
  1391.  
  1392.       ..are equivalent to:
  1393.  
  1394.     _variable = 12
  1395.  
  1396.   The 'setobj' statement can be used to change the value of an object
  1397.   variable in another object, without changing the current object:
  1398.  
  1399.     // sets the value of 'variable' to '12' in the object 'edit'
  1400.     setobj variable 12 "edit"
  1401.  
  1402.   The 'setx' and 'setxobj' statements can be used to change the value of
  1403.   an object variable whose name is not known at compile-time:
  1404.  
  1405.     count = 5
  1406.  
  1407.     // sets the value of 'variable5' to '12'
  1408.     setx "variable" + count  12
  1409.  
  1410.     // sets the value of 'variable5' to '12' in the object 'edit'
  1411.     setxobj "variable" + count  12  "edit"
  1412.  
  1413.   The 'lookup' function can be used to obtain the value of an object
  1414.   variable whose name is not known at compile time:
  1415.  
  1416.     count = 5
  1417.     setx "variable" + count  12
  1418.     say (lookup "variable" + count)   // displays '12'
  1419.  
  1420.   The lookup function can also be used to retrieve the value of an
  1421.   object variable which does not reside in the inheritance hierarchy of
  1422.   the current object:
  1423.  
  1424.     // displays the value of 'variable5' in the object 'edit'
  1425.     say (lookup "variable5" "edit")
  1426.  
  1427.   If the object variable is located in the inheritance hierarchy of the
  1428.   current object and its name is known at compile-time, then a simple
  1429.   variable reference is sufficient:
  1430.  
  1431.     // displays the value of 'variable5'
  1432.     say _variable5
  1433.  
  1434.  
  1435.   The following is a complete list of all the object functions:
  1436.  
  1437.     destroyobject  // destroy an object
  1438.     eventobject    // change the current event object
  1439.     function?      // test for the existence of a function
  1440.     getcurrobj     // get the current (executing) object
  1441.     geteventobj    // get the current event object
  1442.     getobjsize     // get number of variables & functions in an object
  1443.     inheritkeys    // enable/disable key inheritance
  1444.     object?        // test for the existence of an object
  1445.     objtype?       // test object inheritance hierarchy
  1446.     saveobject     // save an object to a file
  1447.     unsetx         // destroy an object variable
  1448.  
  1449.  
  1450.   The Define Statement
  1451.   ────────────────────
  1452.   The 'define' statement can improve the readability of your macros and
  1453.   make them easier to maintain by allowing you to define constants and
  1454.   compile-time functions. The format of the 'define' statement is:
  1455.  
  1456.     define 
  1457.       .
  1458.       <macro statements>
  1459.       .
  1460.     end 
  1461.  
  1462.   The 'define' statement evaluates all macro statements between the
  1463.   'define' and 'end' keywords at compile-time. Any object variables or
  1464.   functions defined within the scope of the 'define' statement have a
  1465.   lifetime limited to the macro language compilation process. No object
  1466.   code is generated for any source code contained within the 'define'
  1467.   statement.
  1468.  
  1469.   Object variables created within the 'define' statement can be
  1470.   referenced as constants outside the scope of the define statement.
  1471.   Similarly, functions defined within the 'define' statement will
  1472.   generate constant values when called outside the 'define' statement.
  1473.   For example:
  1474.  
  1475.     define 
  1476.       _blue = 1
  1477.       _green = 2
  1478.       _cyan = 3
  1479.  
  1480.       // color calculation macro
  1481.       function  color (foreground on background)
  1482.         return  background * 16 + foreground
  1483.       end 
  1484.     end 
  1485.  
  1486.     say _green                // displays '1' (equivalent to 'say 2')
  1487.     say color green on blue   // displays '18' (equivalent to 'say 18')
  1488.     say color blue  on green  // displays '33' (equivalent to 'say 33')
  1489.  
  1490.   Note that the 'object' statement is not permitted within the scope of
  1491.   the 'define' statement. All source code contained within the 'define'
  1492.   statement is compiled and executed in a unique temporary object
  1493.   generated by the compiler. Since there is there is only one such
  1494.   object for all define statements, object variables and functions
  1495.   created in earlier 'define' statements are accessible from within the
  1496.   'define' statements which follow.
  1497.  
  1498.  
  1499.   The Include Statement
  1500.   ─────────────────────
  1501.   When writing macro source code, it is often convenient to place a
  1502.   section of code or definitions which are common to several files in a
  1503.   separate source file. The file can then be shared or 'included' by
  1504.   other source files. This technique avoids excessive duplication of
  1505.   source code and can also make the code easier to change.
  1506.  
  1507.   To include an external macro source file at the current location in
  1508.   your source code, use the 'include' statement. The format of the
  1509.   'include' statement is:
  1510.  
  1511.     include  expression
  1512.  
  1513.   where 'expression' is always evaluated at compile-time, using
  1514.   compile-time functions and variables created with the 'define'
  1515.   statement, if specified. For example:
  1516.  
  1517.     // simple example: includes the file 'c:\common.aml'
  1518.     include "c:\\common.aml"
  1519.  
  1520.     // define compile-time variables and functions
  1521.     define 
  1522.       set include_path "c:\\aurora\\macro\\"
  1523.       function includefile (file)
  1524.         return include_path + file
  1525.       end 
  1526.     end 
  1527.  
  1528.     // complex example: includes the file 'c:\aurora\macro\common.aml'
  1529.     include includefile "common.aml"
  1530.  
  1531.   The 'include' statement can also be used to include compiled macro
  1532.   (.X) files:
  1533.  
  1534.     include "macro.x"
  1535.  
  1536.   This allows macro function libraries to be created and included in
  1537.   your source code, without the need to re-compile the library code. It
  1538.   also allows library '.X' files to be distributed without revealing the
  1539.   source code.
  1540.  
  1541.  
  1542.   Events
  1543.   ──────
  1544.   An important aspect of the macro language is the way in which events
  1545.   are handled. An event can be something that happens in the external
  1546.   world, such as a keypress or a mouse click, or something that happens
  1547.   internally to the editor, such as a timer event or a user-defined
  1548.   event. A macro language function can be defined by the user which is
  1549.   executed in response to the event. In this sense, the macro language
  1550.   is said to be 'event-driven'.
  1551.  
  1552.   When an event occurs, it is immediately placed in an internal area
  1553.   referred to as 'the event queue'. The next time the editor is not busy
  1554.   executing any macros, the event is read from the event queue and
  1555.   translated into a function name, with arguments if applicable. If a
  1556.   function with the same name has been properly defined by the user, the
  1557.   user function will be called automatically by the editor. This
  1558.   user-defined function is called the 'event handling' function. The
  1559.   entire process is referred to as 'dispatching an event'.
  1560.  
  1561.   The complete runtime operation of the editor can be briefly summarized
  1562.   by the following pseudo-code loop:
  1563.  
  1564.     loop forever
  1565.       if an event is in the queue then 
  1566.         read the event from the queue
  1567.         translate the event into a function name
  1568.         call the event-handling function
  1569.       end 
  1570.     end 
  1571.  
  1572.   Many keyboard and mouse events have pre-defined event names enclosed
  1573.   in angled brackets, such as <ctrl x> or <lbutton>. These names should
  1574.   be used as the function name in event handling function definitions.
  1575.   For example:
  1576.  
  1577.     // <lbutton> is the event name for a left mouse button click
  1578.     function <lbutton>
  1579.       say "you pressed the left mouse button"
  1580.     end 
  1581.  
  1582.   For better readability, keyboard event handling functions may be also
  1583.   defined with the 'key' statement, rather than the 'function' statement
  1584.   For example:
  1585.  
  1586.     key <ctrl x>
  1587.       say "you pressed <ctrl x>"
  1588.     end 
  1589.  
  1590.   If the 'key' statement is followed by another 'key' or 'function'
  1591.   statement, the 'end' keyword is not required. For example:
  1592.  
  1593.     key <ctrl x>  say "you pressed <ctrl x>"
  1594.     key <ctrl y>  say "you pressed <ctrl y>"
  1595.     key <ctrl z>
  1596.       .
  1597.       .
  1598.     end 
  1599.  
  1600.  
  1601.   The Current Event Object
  1602.   ────────────────────────
  1603.   The 'current event object' is where the editor dispatches events.
  1604.   Since no macros are usually executing when the editor dispatches an
  1605.   event, there is no 'current' object. Consequently, the editor always
  1606.   looks for the function in an object previously designated as the
  1607.   'current event object'.
  1608.  
  1609.   Only one object can be designated as the current event object at any
  1610.   given time. When the editor is initially started from the DOS command,
  1611.   the default object 'a' becomes the current event object.
  1612.  
  1613.   It is often useful to change the entire behavior of the keyboard and
  1614.   mouse simply by making another object the current event object. For
  1615.   example, when switching from a file manager window to an edit window,
  1616.   the editor simply changes the current event object, and a whole
  1617.   different set of keyboard and mouse event handling functions are
  1618.   enabled.
  1619.  
  1620.   Consider the following example:
  1621.  
  1622.     object edit
  1623.       key <ctrl x>  say "edit window"  end 
  1624.  
  1625.     object fmgr
  1626.       key <ctrl x>  say "file manager window"  end 
  1627.  
  1628.   In the example above, pressing <ctrl x> displays "edit window" when
  1629.   the current event object is the 'edit' object, and "file manager
  1630.   window" when the current event object is the 'fmgr' object.
  1631.  
  1632.   The current event object can be changed by using the builtin function
  1633.   'eventobject'. For example:
  1634.  
  1635.     eventobject "edit"   // designates 'edit' as the new event object
  1636.  
  1637.   The 'geteventobj' builtin function can be used to determine which
  1638.   object is the current event object:
  1639.  
  1640.     say (geteventobj)    // display the current event object
  1641.  
  1642.   Note: if a window has been associated with an event object via the
  1643.   'setwinobj' function, the current event object is automatically
  1644.   changed to the window event object when the window becomes the current
  1645.   window (see 'Windows').
  1646.  
  1647.   When an event is dispatched, and the event handling function is not
  1648.   found in the current event object, the editor will search the
  1649.   inheritance hierarchy of the current event object, in the same way as
  1650.   the hierarchy would be searched for a function call or object variable
  1651.   reference. In this way, an object inherits the event-handling
  1652.   capabilities of its parent objects.
  1653.  
  1654.   The 'pass' function can very useful when intercepting an event for
  1655.   pre-processing or post-processing. In effect, it 'passes on' the event
  1656.   or function call to the parent object(s) of the current object. For
  1657.   example:
  1658.  
  1659.   // mouse left button click
  1660.   function <lbutton>
  1661.     .
  1662.     <pre-processing>     // pre-process the event
  1663.     .
  1664.     pass                 // call <lbutton> in the parent object(s) of
  1665.     .                    //   of the current object
  1666.     .
  1667.     <post-processing>    // post-process the event
  1668.     .
  1669.   end 
  1670.  
  1671.  
  1672.   User Defined Events
  1673.   ───────────────────
  1674.   User-defined events can be placed in the event queue from within an
  1675.   executing macro by using the 'queue' and 'queueobject' builtin
  1676.   functions. Once in the event queue, user-defined events are read and
  1677.   dispatched just like keyboard and mouse events.
  1678.  
  1679.   The 'queue' function places a function call (function + arguments) on
  1680.   the event queue. This effectively defers the execution of the function
  1681.   call until the next time the editor is idle. For example:
  1682.  
  1683.     queue "beep" 400 300
  1684.  
  1685.   In the example above, the function call "beep 400 300" is placed on
  1686.   the event queue. The next time the editor is idle, it will read "beep
  1687.   400 300" from the event queue and evaluate it in the current event
  1688.   object, just as if it were a keyboard or mouse event.
  1689.  
  1690.   The 'queue' function can also be used to simulate an external event
  1691.   such as a key press or a mouse click, without having the external
  1692.   event actually occur. The event handling function will be executed as
  1693.   if the event actually occurred. For example:
  1694.  
  1695.     queue <ctrl x>    // simulates pressing the <ctrl x> key
  1696.     queue <lbutton>   // simulates a left mouse button click
  1697.  
  1698.   User-defined events can also be directed to an explicitly specified
  1699.   object (instead of the current event object), by using the
  1700.   'queueobject' function. For example:
  1701.  
  1702.     queueobject "edit" "beep" 400 300
  1703.  
  1704.   In the example above, the function call "beep 400 300" is placed on
  1705.   the event queue. However, when the editor later reads the event, it
  1706.   will evaluate "beep 400 300" in the object "edit", not in the current
  1707.   event object.
  1708.  
  1709.   To generate an event and dispatch it immediately (synchronously,
  1710.   without using the event queue), the builtin functions 'send' and
  1711.   'sendobject' should be used. For example:
  1712.  
  1713.     send "beep" 400 300
  1714.     sendobject "edit" "beep" 700 200
  1715.  
  1716.   In the examples above, "beep 400 300" is evaluated immediately in the
  1717.   current event object, and "beep 700 200" is evaluated immediately in
  1718.   the object "edit".
  1719.  
  1720.   The 'call' function is similar to the 'send' function, except that the
  1721.   event is dispatched in the current (executing) object, not in the
  1722.   current event object.
  1723.  
  1724.   The following is a complete list of the event functions:
  1725.  
  1726.     call           // dispatch an event in the current object
  1727.     dispatch       // wait for and dispatch the next event
  1728.     endprocess     // return from a recursive invocation of the editor
  1729.     event?         // test if one or more events are in the event queue
  1730.     eventobject    // change the current event object
  1731.     getcurrobj     // get the current (executing) object
  1732.     geteventobj    // get the current event object
  1733.     pass           // call the current function in a parent object
  1734.     process        // invoke the editor recursively
  1735.     purgequeue     // remove all events from the event queue
  1736.     queue          // add an event to the event queue
  1737.     queueobject    // queue an event to a specific object
  1738.     send           // dispatch an event in the current event object
  1739.     sendobject     // dispatch an event to a specified object
  1740.     sizequeue      // change the event queue size
  1741.  
  1742.  
  1743.   Macro Types
  1744.   ───────────
  1745.   Since the editor is entirely written in its own macro language, there
  1746.   are many ways to organize your macro code. Nevertheless, most macros
  1747.   fall into three general categories:
  1748.  
  1749.   - Internal macros
  1750.   - External macros
  1751.   - Command Line macros
  1752.  
  1753.  
  1754.   Internal Macros
  1755.   ───────────────
  1756.   Internal macros are functions or collections of functions contained
  1757.   within the installed macro base of the editor, and are usually
  1758.   executed in response to an event such as keypress or a mouse click.
  1759.   These macros effectively become an integrated part of the editor and
  1760.   are automatically loaded when the editor is started. When the entire
  1761.   editor is compiled with the 'recompile' function (defined in EXT.AML),
  1762.   these macros will become embedded in A.X.
  1763.  
  1764.   Internal macros are typically used to perform common editing tasks
  1765.   unsuitable for 'external' macros. Examples of internal macros include:
  1766.   the keyboard and mouse event handling functions in KBD.AML and
  1767.   MOUSE.AML, the editor extension functions contained in EXT.AML, and
  1768.   the library functions in LIB.X.
  1769.  
  1770.  
  1771.   External Macros
  1772.   ───────────────
  1773.   In addition to internal macros, the editor also provides builtin
  1774.   functions for compiling and executing 'external' macros which reside
  1775.   in separate files. External macros can be individually loaded and
  1776.   executed after the editor is started and are typically used to perform
  1777.   less common editing tasks which do not require them to remain resident
  1778.   in the editor. The macros placed in the MACRO subdirectory at
  1779.   installation are examples of external macros.
  1780.  
  1781.   To compile an external macro source file and generate an executable
  1782.   macro file, use the 'compilemacro' function:
  1783.  
  1784.     compilemacro "macro.aml" "macro.x"
  1785.  
  1786.   The 'geterror' function can be used to retrieve compilation errors:
  1787.  
  1788.     geterror       // get the compilation error (0 = success)
  1789.     geterror 'k'   // get the column where error occurred
  1790.     geterror 'l'   // get the line where error occurred
  1791.  
  1792.   To run an executable macro file, use the 'runmacro' or 'includemacro'
  1793.   functions. For examples:
  1794.  
  1795.     runmacro "macro.x"      // load, execute, and discard 'macro.x'
  1796.     includemacro "macro.x"  // load and execute 'macro.x'
  1797.  
  1798.   'runmacro' loads the macro file and executes it in a temporary object
  1799.   which is descended from the current event object. When the macro is
  1800.   finished executing, the temporary object is destroyed and the macro is
  1801.   discarded.
  1802.  
  1803.   'includemacro' loads the macro file and executes it in the current
  1804.   event object. The macro file remains resident in the editor and any
  1805.   functions or object variables defined in the macro also remain
  1806.   resident. In effect, the 'includemacro' function converts an external
  1807.   macro into an internal macro.
  1808.  
  1809.   Note that macros executed by 'runmacro' and 'includemacro' do not
  1810.   require any special function 'entry points'. The code in an external
  1811.   macro is executed from top to bottom, just as the code within a
  1812.   function would be executed.
  1813.  
  1814.  
  1815.   Command Line Macros
  1816.   ───────────────────
  1817.   Command line macros are compiled external macros which are executed
  1818.   only once when the editor is started. These macros can be specified
  1819.   with the -x option on the DOS command line, or simply named A.X (the
  1820.   default command-line macro). For example:
  1821.  
  1822.     C>a                           // executes 'a.x'
  1823.     C>a -xtest.x                  // executes 'test.x' (but not a.x)
  1824.     C>a -xa.x -xalpha.x -xbeta.x  // executes 'a.x' first, then
  1825.                                   //   'alpha.x', and then 'beta.x'
  1826.  
  1827.   Command line macros can be used to:
  1828.  
  1829.   - perform some type of optional initialization before or after A.X is
  1830.       executed
  1831.   - perform a quick command-line editing operation not requiring
  1832.       the entire editor environment in A.X
  1833.   - completely replace the default editor environment in A.X
  1834.  
  1835.   The Aurora Editor is itself a command line macro contained in the file
  1836.   A.X. A.X is executed by default when the editor is started from the
  1837.   DOS command line without specifying the -x command line option.
  1838.  
  1839.   External source macros can also be compiled by using the 'c' command
  1840.   line option. For example:
  1841.  
  1842.     C>a -ctest.aml -cabc.aml   // compiles 'test.aml' to 'test.x'
  1843.                                //   and 'abc.aml' to 'abc.x'
  1844.  
  1845.  
  1846.   Compilation and Execution Functions
  1847.   ───────────────────────────────────
  1848.   The following is a complete list of the macro compilation and
  1849.   execution functions:
  1850.  
  1851.     builtin functions:
  1852.       compilemacro    // compile a macro source file
  1853.       eval            // evaluate a string as macro source code
  1854.       geterror        // returns error information
  1855.       includemacro    // load and execute a compiled macro file
  1856.       runmacro        // load, execute, and discard a compiled macro
  1857.  
  1858.     extension functions:
  1859.       askcmacro       // prompt to compile a macro source file
  1860.       askeval         // prompt to evaluate a macro expression
  1861.       askimacro       // prompt to include a compiled macro file
  1862.       askrmacro       // prompt to run a compiled macro file
  1863.       compilemacro2   // compile a macro source file (with messages)
  1864.       includemacro2   // load and execute a compiled macro file
  1865.       recompile       // recompile the editor
  1866.       runmacro2       // load, execute, and discard a compiled macro
  1867.       saveconfig      // recompile and save current config variables
  1868.  
  1869.  
  1870.   String Functions
  1871.   ────────────────
  1872.   In addition to the string concatenation '+' and substring '[:]'
  1873.   operators, the macro language provides useful builtin functions for
  1874.   searching and manipulating strings. Several of these functions are
  1875.   discussed briefly here.
  1876.  
  1877.   To determine the size (in characters) of a string or expression, use
  1878.   the 'sizeof' function:
  1879.  
  1880.     a = "apples"
  1881.     b = "oranges"
  1882.     sizeof a               // returns 6
  1883.     sizeof a + b           // returns 13
  1884.     sizeof ''              // returns 0
  1885.     sizeof 1563            // returns 4
  1886.     sizeof 49 + 51         // returns 3
  1887.  
  1888.   The 'pos' function returns the position of one string within another
  1889.   string. Search options may also be specified. For example:
  1890.  
  1891.     pos 'p' "apples"       // searches for 'p' in 'apples', returns 2
  1892.     pos 'p' "apples" 'r'   // searches in reverse for 'p', returns 3
  1893.     pos 'ES' "apples" 'i'  // ignores case, returns 5
  1894.  
  1895.   The 'sub' function replaces all occurrences of a string within another
  1896.   string. Search options can be specified. For example:
  1897.  
  1898.     sub 'p' '112' "apples"      // returns 'a112112les'
  1899.     sub 'es' 'y' "apples"       // returns 'apply'
  1900.     sub 'PL' '' "apples" 'i'    // returns 'apes'
  1901.  
  1902.   The 'upcase' and 'locase' functions change the case of a string:
  1903.  
  1904.     x = locase "APPLES"    // x is "apples"
  1905.     x = upcase "Apples"    // x is "APPLES"
  1906.  
  1907.   To convert integers to binary strings, use the 'char', 'char2', and
  1908.   'char4' functions:
  1909.  
  1910.     char 97                // returns 'a'
  1911.     char2 6261h            // returns 'ab'
  1912.     char4 64636261h        // returns 'abcd'
  1913.  
  1914.   To convert 1, 2, or 4 character binary strings to integers, use the
  1915.   'bin2int' function:
  1916.  
  1917.     bin2int 'a'            // returns 97
  1918.     bin2int 'ab'           // returns 25185
  1919.     bin2int 'abcd'         // returns 1684234849
  1920.  
  1921.   The 'pad' function can be used to pad a string with another string:
  1922.  
  1923.     pad "oranges" 10       // returns "   oranges"
  1924.     pad "oranges" 10 'l'   // returns "oranges   "
  1925.     pad 123 7 'r' '.'      // returns "....123"
  1926.  
  1927.  
  1928.   The following is a complete list of all the string functions:
  1929.  
  1930.     bin2hex   // convert binary strings to hex strings
  1931.     bin2int   // convert a 1, 2, or 4-byte string to an integer
  1932.     char      // convert integers to 1-byte strings
  1933.     char2     // convert integers to 2-byte strings
  1934.     char4     // convert integers to 4-byte strings
  1935.     concat    // concatenate strings together
  1936.     copystr   // duplicate a string one or more times
  1937.     flipcase  // toggle the case of each character in a string
  1938.     hex2bin   // convert hex strings to binary strings
  1939.     icompare  // test strings for equality (ignoring case)
  1940.     joinstr   // combine strings into a 'multistring'
  1941.     locase    // convert a string to lower case
  1942.     pad       // left or right justify a string and pad the string
  1943.     pos       // search for a string within another string
  1944.     poschar   // search for a character class in string
  1945.     posnot    // search for ~character class in string
  1946.     sizeof    // return size of a string (in characters)
  1947.     splitstr  // split a 'multistring' into substrings
  1948.     sub       // replace a substring within another string
  1949.     thousands // convert a number to a thousands-separated string
  1950.     upcase    // convert a string to upper case
  1951.  
  1952.  
  1953.   Miscellaneous Functions
  1954.   ───────────────────────
  1955.   Several important miscellaneous functions are provided by the macro
  1956.   language and are mentioned briefly here.
  1957.  
  1958.   The 'beep' function sounds the PC speaker:
  1959.  
  1960.     beep 700 400        // beeps at 700Hz for 400 milliseconds
  1961.     beep 700            // beeps at 700Hz indefinitely
  1962.     beep                // turns the speaker off
  1963.  
  1964.   To temporarily suspend execution of the editor, use the 'delay'
  1965.   function:
  1966.  
  1967.     delay 1000          // delay for 1000 milliseconds (1 second)
  1968.  
  1969.   The 'halt' function terminates execution of the editor immediately and
  1970.   unconditionally:
  1971.  
  1972.     halt       // terminate the editor immediately and exit to DOS
  1973.  
  1974.   To convert a decimal or hexadecimal number to a string representing
  1975.   the number in a new base, use the 'base' function:
  1976.  
  1977.     x = base 141 16                 // returns '8D' (base 16)
  1978.     x = base 141 8                  // returns '215' (base 8)
  1979.     x = base 141 5                  // returns '1031' (base 5)
  1980.     x = base 141 2                  // returns '10001101' (base 2)
  1981.  
  1982.   The 'eval' function evaluates a string of macro source code. This
  1983.   allows macro code to be dynamically constructed and executed from
  1984.   within an executing macro. For example:
  1985.  
  1986.     eval "beep " + " 700 300"      // beeps the speaker
  1987.     a = 40
  1988.     x = eval '3 + ' + a [1]        // x is '7'
  1989.  
  1990.   Note that local and global variables defined outside of the scope of
  1991.   the eval string are not accessible from within the 'eval' function.
  1992.  
  1993.   The following is a complete list of all the miscellaneous functions:
  1994.  
  1995.     arg    // access function arguments
  1996.     base   // convert a number to a string representing a new base
  1997.     beep   // beep the PC speaker
  1998.     delay  // suspend execution of a macro
  1999.     eval   // evaluate a string as macro source code
  2000.     exec   // execute a DOS program
  2001.     halt   // exit to DOS immediately
  2002.     peek   // return a copy of a DOS memory area
  2003.     poke   // modify a DOS memory area
  2004.     rand   // generate a random number
  2005.  
  2006.  
  2007.   Buffers
  2008.   ───────
  2009.   Perhaps the most basic concept in the editor is a text 'buffer'. A
  2010.   buffer is a file as it exists within the editor. Buffers may contain
  2011.   text from a file on disk, new text entered from within the editor, or
  2012.   both. Buffers are also used for manipulating temporary internal files.
  2013.  
  2014.   The editor maintains an internal list of buffers called the 'buffer
  2015.   list', with the 'current' buffer as the first buffer in the list. Each
  2016.   buffer is identified by a unique 'bufferid'. Not specifying a bufferid
  2017.   (or specifying a null bufferid) for many of the builtin buffer
  2018.   functions usually indicates that the 'current' buffer should be used.
  2019.  
  2020.   There are many functions which can be used to manipulate buffers. The
  2021.   most important functions are discussed briefly here. Most of these
  2022.   functions can be specified with several arguments, but are shown here
  2023.   in their simplest forms. See the AML Function Reference (FUNCTION.DOX)
  2024.   for a complete listing of buffer functions and their arguments.
  2025.  
  2026.   Buffers can be created by using functions like 'loadbuf' and
  2027.   'createbuf', saved with 'savebuf', and destroyed with 'destroybuf'.
  2028.   For example:
  2029.  
  2030.     if loadbuf "file.ext" then       // load a file into a buffer
  2031.       .
  2032.       <modify the text buffer>
  2033.       .
  2034.       savebuf "file.ext"             // save the buffer to a file
  2035.       destroybuf                     // destroy the buffer
  2036.     end 
  2037.  
  2038.   The 'databuf' statement can be used to define a buffer within a macro,
  2039.   without requiring a separate file:
  2040.  
  2041.     databuf "abc"                    // define buffer 'abc'
  2042.       "first line"                   // 1st line
  2043.       x + y                          // 2nd line
  2044.       "last line"                    // 3rd line
  2045.     end 
  2046.  
  2047.   Although these functions and statements are preferred for low-level
  2048.   manipulation of files within the editor, they do not associate a
  2049.   buffer with a window for interactive, event-driven editing. Library
  2050.   functions such as 'open' should be used to create or load buffers and
  2051.   display them for on-screen editing. For example:
  2052.  
  2053.     open "file.ext"   // load 'file.ext' into a new edit window
  2054.  
  2055.   Likewise, other library functions such as 'save' and 'close' should be
  2056.   used to save and destroy these buffers:
  2057.  
  2058.     save     // save the buffer in the current edit window
  2059.     close    // close the current edit window
  2060.  
  2061.   See 'Primary Editing Functions' for a complete listing of these
  2062.   higher-level functions.
  2063.  
  2064.   To retrieve a character from a buffer, use the 'getchar' function:
  2065.  
  2066.     // is the character at the cursor a blank?
  2067.     if getchar == ' ' then 
  2068.       .
  2069.     end 
  2070.  
  2071.   To retrieve a line or a portion of a line from a buffer, use the
  2072.   'gettext' function:
  2073.  
  2074.     // display the line at the cursor
  2075.     say "The line at the cursor is: " + gettext
  2076.  
  2077.   The 'getlinelen' and 'getlines' functions can be used to return the
  2078.   length of a line, and the number of lines in a buffer. For example:
  2079.  
  2080.     // is the cursor on a blank line?
  2081.     if not getlinelen then 
  2082.       .
  2083.       .
  2084.     end 
  2085.  
  2086.     // test if the number of lines in the current buffer
  2087.     // is greater than 5000
  2088.     if getlines >= 5000 then 
  2089.       say "This is a large file!"
  2090.     end 
  2091.  
  2092.   To enter text strings in a line, use the 'instext', 'ovltext', and
  2093.   'writetext' builtin functions, or the extension function 'write':
  2094.  
  2095.     instext "some text"    // insert 'some text' at the cursor
  2096.     ovltext "some text"    // overlay 'some text' at the cursor
  2097.     writetext "some text"  // insert or overlay 'some text' at the
  2098.                            //   cursor depending on the insert mode and
  2099.                            //   move the cursor to the end of the string
  2100.     write "some text"      // enter a string at the cursor, with support
  2101.                            //   for window settings such as word wrap,
  2102.                            //   translate, and match character
  2103.  
  2104.   The function 'delchar' will delete text in a line:
  2105.  
  2106.     delchar                // deletes the character at the cursor
  2107.     delchar 10             // deletes 10 characters at the cursor
  2108.  
  2109.   To insert new lines into a buffer or delete lines from a buffer, use
  2110.   the 'insline', 'insabove', and 'delline' functions:
  2111.  
  2112.     insline                // inserts a new blank line after the cursor
  2113.     insline "some text"    // inserts the new line "some text" after
  2114.                            //   the cursor
  2115.     insabove               // inserts a new blank line above the cursor
  2116.     delline                // deletes the line at the cursor
  2117.  
  2118.   The 'getcurrbuf' and 'getprevbuf' functions may be used to traverse
  2119.   existing buffers in the editor:
  2120.  
  2121.     buffer = getcurrbuf              // get the 'current' buffer
  2122.     while buffer do 
  2123.       .
  2124.       .
  2125.       buffer = getprevbuf buffer     // get the previous buffer
  2126.     end 
  2127.  
  2128.   The function 'hidebuf' will hide a buffer from the 'getprevbuf'
  2129.   function, so that it can not be traversed:
  2130.  
  2131.     hidebuf    // hide the current buffer
  2132.  
  2133.   'hidebuf' will also prevent buffers from being displayed on file lists
  2134.   generated by the editor library (LIB.X).
  2135.  
  2136.   The 'setbufname' function associates a descriptive name with a buffer,
  2137.   and the 'getbufname' function retrieves this name. For buffers created
  2138.   and manipulated with library functions (such as 'open') this name
  2139.   should always be a fully qualified file name:
  2140.  
  2141.     setbufname "C:\\FILE.EXT"  // change the name of the current buffer
  2142.     say (getbufname)           // display the name of the current buffer
  2143.  
  2144.  
  2145.   The following is a complete list of all the buffer functions:
  2146.  
  2147.     statements
  2148.       databuf       // define or add to a data buffer
  2149.  
  2150.     builtin functions:
  2151.       actualrow     // get the actual row over an apparent distance
  2152.       addline       // add a line to the end of a buffer
  2153.       apparentrow   // get the apparent row over an actual distance
  2154.       asciibuf      // create a buffer of ASCII characters
  2155.       bufchanged?   // test if buffer is modified
  2156.       buffer?       // test if a buffer exists
  2157.       bufferflag    // change buffer flags
  2158.       bufferflag?   // get buffer flags
  2159.       createbbuf    // create a new binary buffer
  2160.       createbuf     // create a new buffer
  2161.       currbuf       // change the current buffer
  2162.       delchar       // delete text on a line
  2163.       delline       // delete a line
  2164.       destroybuf    // destroy a buffer
  2165.       findbuf       // find a buffer with a given buffer name
  2166.       getbinarylen  // get binary line length used to load a buffer
  2167.       getbufname    // get the buffer name
  2168.       getchar       // get a character from a buffer
  2169.       getcurrbuf    // get the current bufferid
  2170.       getlinebeg    // get the starting column of a line
  2171.       getlinelen    // get the length of a line
  2172.       getlines      // get the total number of lines in buffer
  2173.       getloadinfo   // get directory information after loadbuf/insertbuf
  2174.       getprevbuf    // get the previous bufferid
  2175.       gettext       // get a line or a portion of a line from a buffer
  2176.       gotobuf       // change the default buffer for builtin functions
  2177.       hidebuf       // hide a buffer
  2178.       insabove      // insert a line before another line
  2179.       insertbuf     // insert a file into a buffer
  2180.       insline       // insert a line after another line
  2181.       instext       // insert a string into a line
  2182.       joinline      // join two lines into one line
  2183.       lineflag      // change line flags
  2184.       lineflag?     // get line flags
  2185.       loadbuf       // create a new buffer from a file or directory
  2186.       ovltext       // overlay a string onto a line
  2187.       printbuf      // print a buffer
  2188.       savebuf       // save a buffer to a file
  2189.       setbufname    // set the name associated with a buffer
  2190.       splitline     // split a line into two lines
  2191.       trunc?        // test if buffer was truncated when loaded
  2192.       undosize      // set the undo stack size for a buffer
  2193.       writetext     // insert or overlay a string in a line
  2194.  
  2195.     extension functions:
  2196.       backsp        // delete char to the left (with joinline)
  2197.       caseword      // change the case of the word at the cursor
  2198.       centerline    // center the line at the cursor
  2199.       commentline   // comment the line at the cursor
  2200.       delchar2      // delete the char at the cursor (with joinline)
  2201.       delword       // delete right word at the cursor
  2202.       enter         // enter key
  2203.       getword       // get the word at the cursor or at a column
  2204.       insline2      // insert a line with autoindent
  2205.       literal       // prompt to enter the next character literally
  2206.       livewrap      // live word wrap support
  2207.       splitline2    // split a line with autoindent
  2208.       swapline      // swap lines at the cursor
  2209.       tabfile       // detab or entab the current file
  2210.       timestamp     // enter the date and time at the cursor
  2211.       write         // enter a string at the cursor
  2212.  
  2213.  
  2214.   Cursors
  2215.   ───────
  2216.   A cursor identifies a movable column and row position in a buffer and
  2217.   usually marks the default location where text is entered. Cursors are
  2218.   normally visible in the window which displays the buffer.
  2219.  
  2220.   A cursor is always associated with only one buffer and may be created
  2221.   only after the buffer is created. All cursors associated with a buffer
  2222.   are automatically destroyed when the buffer is destroyed.
  2223.  
  2224.   For each buffer, the editor maintains an internal list of cursors
  2225.   called the 'cursor list', with the 'current' cursor as the first
  2226.   cursor in the list. Each cursor is identified by a unique 'cursorid'.
  2227.   Not specifying a cursorid (or specifying a null cursorid) for many of
  2228.   the builtin cursor functions usually indicates that the 'current'
  2229.   cursor should be used. Although it is possible to associate many
  2230.   cursors with a buffer, most buffers have only one cursor.
  2231.  
  2232.   There are many functions which can be used to manipulate cursors. The
  2233.   most important functions are discussed briefly here.
  2234.  
  2235.   The easiest way to create a cursor is to simply use a cursor function.
  2236.   If no cursor is associated with the current buffer, a cursor is
  2237.   automatically created before the function is executed. For example:
  2238.  
  2239.     if createbuf then    // create a new buffer
  2240.       right              // create a cursor and move it to the right
  2241.       .                  //   by 1 column
  2242.     end 
  2243.  
  2244.   New cursors can also be created and destroyed with the 'setcursor' and
  2245.   'destroycursor' builtin functions (see the AML Function Reference).
  2246.  
  2247.  
  2248.   Note: the following cursor functions all operate on the 'current'
  2249.   cursor. No cursorid is specified.
  2250.  
  2251.   To retrieve the column and row position of the cursor, use the
  2252.   'getcol' and 'getrow' functions:
  2253.  
  2254.     // display the cursor position
  2255.     say "You're at column: " + getcol + ", row: " + getrow
  2256.  
  2257.   The 'insert?' function can be used to test whether or not the cursor
  2258.   is in insert or overstrike mode:
  2259.  
  2260.     // display the insert mode
  2261.     say "Insert mode " + ( if? insert? "ON" "OFF" )
  2262.  
  2263.   To move the cursor to a specific column and/or row, use the 'col',
  2264.   'row', and 'gotopos' functions:
  2265.  
  2266.     col 5           // move the cursor to column 5
  2267.     row (getlines)  // move the cursor to the last line in the buffer
  2268.     gotopos 14 671  // move the cursor to column 14, line 671
  2269.  
  2270.   The 'left', 'right', 'up', and 'down' functions can be used to move
  2271.   the cursor a relative distance away from the current cursor position:
  2272.  
  2273.     left     // move the cursor left 1 column
  2274.     right 3  // move the cursor right 3 columns
  2275.     up       // move the cursor up 1 line
  2276.     down 6   // move the cursor down 6 lines
  2277.  
  2278.   Since these functions return TRUE if the cursor is moved and FALSE if
  2279.   cursor cannot be moved, they can be used in conditional statements.
  2280.   For example:
  2281.  
  2282.     row 1
  2283.     repeat 
  2284.       .
  2285.       <do something for every line in the buffer>
  2286.       .
  2287.     until not down
  2288.  
  2289.   To save and restore the current cursor position on an internal stack
  2290.   associated with the current buffer, use the 'pushcursor' and
  2291.   'popcursor' functions. For example:
  2292.  
  2293.     pushcursor    // save the cursor position
  2294.     row 1
  2295.     repeat 
  2296.       .
  2297.       <do something for every line in the buffer>
  2298.       .
  2299.     until not down
  2300.     popcursor     // restore the cursor position
  2301.  
  2302.  
  2303.   The following is a complete list of all the cursor functions:
  2304.  
  2305.     builtin functions:
  2306.       col            // move the cursor to a column
  2307.       colorcursor    // change the cursor color
  2308.       currcursor     // change the current cursor
  2309.       cursor?        // test if a cursor exists
  2310.       destroycursor  // destroy a cursor and any associated window
  2311.       down           // move the cursor down
  2312.       getcol         // get the cursor column
  2313.       getcurrcurs    // get the current cursor
  2314.       getcurswin     // get window associated with a cursor
  2315.       getprevcurs    // get the previous cursor
  2316.       getrow         // get the cursor row
  2317.       gotopos        // move the cursor (absolute)
  2318.       insert?        // get cursor insert/overstrike mode
  2319.       lastpos        // move the cursor to the last cursor position
  2320.       left           // move the cursor left
  2321.       movepos        // move the cursor (relative)
  2322.       popcursor      // restore the cursor position from the cursor stack
  2323.       pushcursor     // save the cursor position on the cursor stack
  2324.       right          // move the cursor right
  2325.       row            // move the cursor to a row
  2326.       setcursor      // create a new cursor or change the cursor state
  2327.       up             // move the cursor up
  2328.  
  2329.     extension functions:
  2330.       enter        // the enter key
  2331.       nextword     // find the next word
  2332.       prevword     // find the previous word
  2333.       tableft      // tab left
  2334.       tabright     // tab right
  2335.  
  2336.  
  2337.   Bookmarks
  2338.   ─────────
  2339.   A bookmark identifies a stationary column and row position in a
  2340.   buffer. Bookmarks are often used to mark a position in the buffer to
  2341.   which the cursor will later be returned. Bookmarks are not visible in
  2342.   the window which displays the buffer.
  2343.  
  2344.   Like cursors, a bookmark is always associated with a specific buffer
  2345.   and may be created only after the buffer is created. All bookmarks
  2346.   associated with a buffer are automatically destroyed when the buffer
  2347.   is destroyed.
  2348.  
  2349.   For each buffer, the editor maintains an internal list of bookmarks
  2350.   called the 'bookmark list', with the 'current' bookmark as the first
  2351.   bookmark in the list. Each bookmark is identified by a unique
  2352.   'bookmarkid' (the name of the bookmark). Not specifying a bookmarkid
  2353.   (or specifying a null bookmarkid) for many of the builtin bookmark
  2354.   functions usually indicates that the 'current' bookmark should be
  2355.   used.
  2356.  
  2357.   To set a bookmark at the current cursor position, use the 'setbook'
  2358.   function. If the bookmark already exists, it is moved to the new
  2359.   position, otherwise a new bookmark is created. For example:
  2360.  
  2361.     setbook 'A'             // set bookmark 'A' at the cursor
  2362.     setbook "bookmark #1"   // set bookmark 'bookmark #1' at the cursor
  2363.  
  2364.   The 'destroybook' function will remove the bookmark:
  2365.  
  2366.     destroybook 'A'         // remove bookmark 'A'
  2367.  
  2368.   To move the cursor to a specific bookmark, use the 'gotobook'
  2369.   function:
  2370.  
  2371.     gotobook 'A'            // moves the cursor to bookmark 'A'
  2372.  
  2373.  
  2374.   The following is a complete list of the bookmark functions:
  2375.  
  2376.     builtin functions:
  2377.       currbook     // change the current bookmark
  2378.       destroybook  // destroy a bookmark
  2379.       getbookbuf   // get the buffer associated with a bookmark
  2380.       getcurrbook  // get the current bookmark for a buffer
  2381.       getprevbook  // get the previous bookmark in the buffer
  2382.       gotobook     // move the cursor to a bookmark
  2383.       setbook      // create a new bookmark or move an existing bookmark
  2384.  
  2385.     extension functions:
  2386.       askbook      // prompt for a bookmark to move to
  2387.       cyclebook    // cycle though all existing bookmarks
  2388.       gotobook2    // move cursor to a bookmark (with messages)
  2389.       placebook    // set a bookmark (with messages)
  2390.       quickbook    // place a 'quick' bookmark
  2391.  
  2392.  
  2393.   Marks
  2394.   ─────
  2395.   A mark defines an area of text in a buffer. Marks are usually visible
  2396.   in the window which displays the buffer. Once an area of text is
  2397.   marked, 'block' functions may be used to manipulate the text within
  2398.   the mark.
  2399.  
  2400.   A mark is always associated with a specific buffer and may be created
  2401.   only after the buffer is created. All marks associated with a buffer
  2402.   are automatically destroyed when the buffer is destroyed.
  2403.  
  2404.   For each buffer, the editor maintains an internal list of marks called
  2405.   the 'mark list', with the 'current' mark as the first mark in the
  2406.   list. Each mark is identified by a unique 'markid'. Not specifying a
  2407.   markid (or specifying a null markid) for many of the builtin mark
  2408.   functions usually indicates that the default markid '*' should be used
  2409.   (but not necessarily the current mark).
  2410.  
  2411.   Although it is possible to associate many marks with a buffer, most
  2412.   buffers have only one mark (with the default markid '*'), or no marks
  2413.   at any given time.
  2414.  
  2415.   There are many builtin functions which can be used to manipulate
  2416.   marks. The most important functions are discussed briefly here. Most
  2417.   of these functions can be specified with several arguments, but are
  2418.   shown here in their simplest forms. See the AML Function Reference for
  2419.   a complete listing of buffer functions and their arguments.
  2420.  
  2421.   Marks can be created with the 'markline', 'markcolumn', 'markchar',
  2422.   and 'markstream' functions, and destroyed with the 'destroymark'
  2423.   function. The type of mark created depends on which function is used.
  2424.   For example:
  2425.  
  2426.     markline                     // mark the line at the cursor and
  2427.                                  //   begin marking a series of lines
  2428.     markline 1 (getlines)        // mark the entire buffer
  2429.     markcolumn                   // begin marking a series of columns
  2430.     markcolumn 3 3 1 (getlines)  // mark the third column in the entire
  2431.                                  //   buffer
  2432.     markchar                     // mark the character at the cursor and
  2433.                                  //   begin marking a stream of chars
  2434.     markstream                   // begin marking a stream of characters
  2435.     destroymark                  // destroy the mark
  2436.  
  2437.   When any of the above functions are specified without arguments, the
  2438.   mark can be extended by moving the cursor until the function is called
  2439.   a second time. For example:
  2440.  
  2441.     row 1               // move the cursor to line 1
  2442.     markline            // mark the first line
  2443.     row 5               // extend the mark to line 5
  2444.     row (getlines)      // extend the mark to the whole buffer
  2445.     markline            // stop the cursor extension of the mark
  2446.  
  2447.   The 'mark?' function tests for the existence of a mark:
  2448.  
  2449.     if mark? then 
  2450.        .
  2451.       <do if the mark '*' exists>
  2452.        .
  2453.     end 
  2454.  
  2455.   The 'inmark?' function tests if the current cursor lies within a mark:
  2456.  
  2457.     key <del>           // the <del> key is pressed
  2458.       if inmark? then   // if the cursor is within a mark..
  2459.         deleteblock     // then delete the text in the mark
  2460.       else              // otherwise..
  2461.         delchar         // delete the character at the cursor
  2462.       end 
  2463.     end 
  2464.  
  2465.   The 'copymark' function makes a copy of an existing mark:
  2466.  
  2467.     copymark '*' 'T'    // now there are two marks: the orginal
  2468.                         // mark '*', and the new mark 'T'
  2469.  
  2470.   When the editor is started, the default markid is '*'. It is often
  2471.   useful to change the default markid when working with temporary marks
  2472.   to avoid altering marks created by the user (with the markid '*'). The
  2473.   'usemark' function is provided for this purpose:
  2474.  
  2475.     usemark 'T'         // change the default markid to 'T'
  2476.     markline            // create a temporary line mark
  2477.     shiftblock 1        // shift the marked text right one column
  2478.     destroymark         // destroy the temporary mark
  2479.     usemark             // always change the default markid back to '*'
  2480.  
  2481.  
  2482.   The following is a complete listing of all the mark functions:
  2483.  
  2484.     builtin functions:
  2485.       colormark      // change the mark color
  2486.       copymark       // mark a copy of a mark
  2487.       currmark       // change the current (top) mark
  2488.       destroymark    // destroy a mark
  2489.       extendmark     // extend the current mark to the cursor position
  2490.       getcurrmark    // get the current mark for a buffer
  2491.       getmarkbot     // get the bottom row of a mark
  2492.       getmarkbuf     // get the buffer associated with the mark
  2493.       getmarkcols    // get the mark width
  2494.       getmarkleft    // get the left column of mark
  2495.       getmarkright   // get the right column of mark
  2496.       getmarkrows    // get the mark height
  2497.       getmarktop     // get top row of a mark
  2498.       getmarktype    // get the mark type
  2499.       getmarkuse     // get the default markid
  2500.       getprevmark    // get the previous mark
  2501.       inmark?        // test if a cursor position is inside a mark
  2502.       mark?          // test for the existence of a mark
  2503.       markchar       // begin or extend a char mark
  2504.       markcolumn     // begin or extend a column mark
  2505.       markline       // begin or extend a line mark
  2506.       markstream     // being or extend a stream mark
  2507.       stopmark       // stop the cursor extension of a mark
  2508.       usemark        // change the default markid
  2509.  
  2510.     extension functions:
  2511.       getmarktext    // get top line of text in a mark
  2512.       markeol        // mark to the end of the current line
  2513.       markpara       // mark the paragraph at the cursor
  2514.       markword       // mark the word at the cursor
  2515.       smark          // allow CUA <shift> marking after cursor movement
  2516.  
  2517.  
  2518.   The following is a complete listing of all the 'block' functions which
  2519.   can be used to manipulate a marked block of text:
  2520.  
  2521.     builtin functions:
  2522.       caseblock      // change the case of text in a mark
  2523.       copyblock      // copy the text in a mark
  2524.       copyblockover  // overlay the text in a mark over other text
  2525.       deleteblock    // delete the text in a mark
  2526.       tabblock       // expand the tab characters (ASCII 9) in a mark
  2527.       fillblock      // fill a mark with a repeating character or string
  2528.       foldblock      // manipulate folds in a mark
  2529.       formatblock    // reformat the text in a mark
  2530.       justblock      // justify the text in a mark
  2531.       moveblock      // move the text in a mark
  2532.       printblock     // print the text in a mark
  2533.       saveblock      // save the text in a mark
  2534.       shiftblock     // shift the text in a mark left or right
  2535.       sortblock      // sort the text in a mark
  2536.  
  2537.     extension functions:
  2538.       copyblock2     // copy a block (or a line) of text
  2539.       deleteblock2   // delete a block of text
  2540.       fillblock2     // prompt to fill a mark with a string
  2541.       formatblock2   // reformat a block or paragraph
  2542.       justblock2     // justify a block of text between margins
  2543.       moveblock2     // move a block of text
  2544.       moveblockover  // move a block of text over other text
  2545.       quote          // quote a paragraph or a block of text
  2546.       saveblock2     // save a block of text
  2547.       sortblock2     // sort a block of text
  2548.  
  2549.     Clipboard support is implemented in the following extension
  2550.     functions by using the 'mark' and 'block' functions:
  2551.  
  2552.       askclip        // prompt to change the current clipboard
  2553.       clear          // erase the contents of a clipboard
  2554.       copy           // copy or copy-append to a clipboard
  2555.       cut            // cut or cut-append to a clipboard
  2556.       paste          // paste or paste-over from a clipboard
  2557.  
  2558.  
  2559.   Undo and Redo
  2560.   ─────────────
  2561.   The ability to 'undo' and 'redo' certain editor functions is an
  2562.   advanced feature of the macro language. This feature allows you to
  2563.   backtrack and retrace the changes made to a buffer. The types of
  2564.   'undoable' functions include:
  2565.  
  2566.     - functions which modify buffers
  2567.     - functions which create or modify marks
  2568.     - functions which create or modify folds
  2569.     - functions which move the cursor (under special circumstances)
  2570.  
  2571.   In general, all text changes, folding, and marking can be undone.
  2572.   Cursor movements are also undone, but only when associated with text
  2573.   changes, folding, and marking, or explicitly specified with the
  2574.   'undocursor' function.
  2575.  
  2576.   To allow buffer changes to be undoable, an undo/redo stack must be
  2577.   created for the buffer by using the 'undosize' function. For example:
  2578.  
  2579.     undosize 500    // allow a maximum of 500 changes to be undone
  2580.  
  2581.   The 'undo' function can then be used to undo changes to the buffer,
  2582.   one at a time:
  2583.  
  2584.     undo    // undo one change
  2585.  
  2586.   Changes which were undone with 'undo' can be reinstated with the
  2587.   'redo' function:
  2588.  
  2589.     redo    // redo one change
  2590.  
  2591.   Multiple changes to a buffer can be grouped together as one undoable
  2592.   operation by using the 'undobegin' and 'undoend' functions. For
  2593.   example:
  2594.  
  2595.     undobegin            // beginning of an undoable group
  2596.     delline              // 1st change to the buffer
  2597.     instext "a string"   // 2nd change to the buffer
  2598.     insline              // 3rd change to the buffer
  2599.     undoend              // end of an undoable group
  2600.      .
  2601.      .
  2602.     undo                 // all 3 changes are undone as one operation
  2603.  
  2604.   Undoable groups can be nested. In this case, the outermost
  2605.   undobegin-undoend pair denotes the undoable group. The inner
  2606.   undobegin-undoend pairs are ignored.
  2607.  
  2608.   The 'undocursor' function can also be used to save the current cursor
  2609.   position as an undoable operation on the undo/redo stack.
  2610.  
  2611.   The following is a complete list of the undo and redo functions:
  2612.  
  2613.     redo         // redo the last change or group of changes
  2614.     undo         // undo the last change or group of changes
  2615.     undobegin    // start a group of undoable operations
  2616.     undocursor   // save the cursor position on the undo/redo stack
  2617.     undoend      // end a group of undoable operations
  2618.     undosize     // associate an undo/redo stack with a buffer
  2619.  
  2620.  
  2621.   Search and Replace
  2622.   ──────────────────
  2623.   The editor provides many functions for searching through files and
  2624.   replacing strings, and for scanning multiple files for a string.
  2625.  
  2626.   The builtin functions 'find' and 'replace' will search for, and
  2627.   replace strings in a buffer. Many different search options can be
  2628.   specified in various combinations, and searches can be confined to a
  2629.   mark. For example:
  2630.  
  2631.     find "apples" "*ir"
  2632.       // searches for 'apples' (case insensitive) starting at the cursor
  2633.       //   and searching toward the beginning of the buffer
  2634.  
  2635.     replace "apples" "oranges" "ag"
  2636.       // replaces all occurrences of "apples" with "oranges" in the
  2637.       //   current buffer
  2638.  
  2639.   See the AML Function Reference for a complete description of the
  2640.   'find' and 'replace' functions, and search options.
  2641.  
  2642.   The higher-level library function 'search' can also be used for both
  2643.   searching and replacing. Unlike the 'find' and 'replace' functions,
  2644.   arguments to the 'search' function are specified as one combined
  2645.   'multistring'. For example:
  2646.  
  2647.     search "apples/ir*"
  2648.     search "apples/oranges/ag"
  2649.  
  2650.   See the AML Function Reference for complete description of the
  2651.   'joinstr', 'splitstr' functions, and multistrings.
  2652.  
  2653.   The functions 'scanfile' and 'searchfiles' will both scan multiple
  2654.   files for a string and create a new file manager window showing all
  2655.   files where the string was found. Whereas separate arguments are
  2656.   specified for 'scanfile', arguments to 'searchfiles' are specified as
  2657.   one combined 'multistring'. For example:
  2658.  
  2659.     scanfiles "C:\\*.TXT"  "apples"  "iw"  // separate search arguments
  2660.  
  2661.     searchfiles "apples/C:\\*.TXT/iw"      // 'multistring' arguments
  2662.  
  2663.  
  2664.   The following is a complete list of the search and replace functions:
  2665.  
  2666.     builtin functions:
  2667.       find         // search for a string
  2668.       replace      // search for a string, replace with another string
  2669.  
  2670.     library functions:
  2671.       gotoerror    // go to the compiler error on the current line
  2672.       gotomatch    // find the matching character
  2673.       scanfiles    // scan files for a string
  2674.       search       // search or replace within the current file
  2675.  
  2676.     extension functions:
  2677.       askcol       // prompt for a column to go to
  2678.       askfind      // prompt for a search (multistring)
  2679.       askfindo     // prompt for find occurrences of a string
  2680.       askrepl      // prompt for search and replace (multistring)
  2681.       askrow       // prompt for a row to go to
  2682.       askscan      // prompt to scan files for a string
  2683.       col2         // go to a column (absolute or relative +/-)
  2684.       findlast     // repeat the last search/replace
  2685.       findlasto    // find occurrences of the last search string
  2686.       findo        // find occurrences of a string
  2687.       gotomark     // go to an edge of a mark
  2688.       gotomatch2   // find the matching char (with highlight)
  2689.       isearch      // incremental search
  2690.       row2         // go to a row (absolute or relative +/-)
  2691.       search2      // search/replace with messages and highlighting
  2692.       searchfiles  // scan files for a string (multistring arguments)
  2693.  
  2694.  
  2695.   Folds
  2696.   ─────
  2697.   Folds are an advanced feature of the editor which allow you to escape
  2698.   the normal 'flat text' mode of editing. Using folds, you can impose a
  2699.   hierarchal structure on your text, giving it the appearance and
  2700.   behaviour of an electronic outline.
  2701.  
  2702.   Using folding functions, multiple lines of text in a buffer can be
  2703.   'folded together' and made to appear as one line in a window. Any
  2704.   number of folds of any size can be created. Folds can be nested by
  2705.   folding a group of lines which already contain other folds. Folds
  2706.   within a fold are referred to as 'subfolds'.
  2707.  
  2708.   Folds can also be opened for viewing or editing, and saved along with
  2709.   the text in a buffer. All folding operations are 'undoable' (see 'Undo
  2710.   and Redo').
  2711.  
  2712.   Folds may be also excluded from searching by the specifying the 's'
  2713.   (skip) search option. See the 'find' function in the AML Function
  2714.   Reference for description of search options.
  2715.  
  2716.   The following is a complete list of the folding functions:
  2717.  
  2718.     builtin functions:
  2719.       closefold      // close a fold (and optionally, subfolds)
  2720.       createfold     // create a one-line 'open' fold
  2721.       destroyfold    // destroy a fold (and optionally, subfolds)
  2722.       fold?          // test for the existence of a closed fold
  2723.       foldblock      // manipulate folds within a mark
  2724.       getfold        // get information about a fold
  2725.       openfold       // open a fold (and optionally, subfolds)
  2726.  
  2727.     extension functions:
  2728.       foldall        // manipulate all folds in a buffer
  2729.       foldline       // fold or unfold a line
  2730.  
  2731.  
  2732.   Timers
  2733.   ──────
  2734.   A 'timer' is a macro language facility that allows user-defined events
  2735.   to be generated automatically at timed intervals, or at a specific
  2736.   time and date.
  2737.  
  2738.   To set a timer to call a function only once after a specified time
  2739.   interval has elapsed, use the 'settimer' function. For example:
  2740.  
  2741.     settimer 'mytimer' 1500 '' 'beep' 700 300
  2742.       // sets the timer 'mytimer' to execute the function call 'beep 700
  2743.       //   300' in the current event object 1.5 seconds from now
  2744.  
  2745.   Note that:
  2746.  
  2747.     settimer 'mytimer' 0 '' 'beep' 700 300   // time interval is zero
  2748.  
  2749.       //..is equivalent to:
  2750.  
  2751.     queue 'beep' 700 300
  2752.  
  2753.   A timer specified with the 'settimer' function is automatically
  2754.   destroyed after one event is generated. To set a timer which repeats
  2755.   at regular intervals, use the 'setrepeat' function. For example:
  2756.  
  2757.     setrepeat 'mytimer' 1500 '' 'beep' 700 300
  2758.       // sets the timer 'mytimer' to execute the function call 'beep 700
  2759.       //   300' every 1.5 seconds in the current event object
  2760.  
  2761.   Specifying a zero time interval in the 'setrepeat' function will
  2762.   create a repeating timer which generates an event whenever the editor
  2763.   is idle. This can be used to create 'idle-time' macros:
  2764.  
  2765.     setrepeat 'mytimer' 0 '' 'myfunction'
  2766.       // sets the timer 'mytimer' to call 'myfunction' in the
  2767.       //   current event object whenever the editor is idle
  2768.  
  2769.   A timer specified with the 'setrepeat' function will continue to
  2770.   'fire' until it is destroyed with the 'destroytimer' function:
  2771.  
  2772.     destroytimer 'mytimer'   // destroys the timer 'mytimer'
  2773.  
  2774.   To create a timer which generates an event at a specific date and
  2775.   time, use the 'setalarm' function:
  2776.  
  2777.     setalarm 'mytimer'  // set the alarm timer 'mytimer' to fire:
  2778.        1995             // in year 1995
  2779.        1                // on january
  2780.        12               // 12th,
  2781.        -1               // any day of the week
  2782.        22               // at 10 o'clock at night
  2783.         0               // zero minutes past 10
  2784.         0               // zero seconds past zero minutes
  2785.        ''               // dispatch in the current event object
  2786.        'beep' 700 300   // execute the function call 'beep 700 300'
  2787.  
  2788.   If -1 is specified for any of the 'setalarm' arguments, those arguments
  2789.   become 'wildcards' (the timer will fire for any values of those
  2790.   arguments). For example:
  2791.  
  2792.     // sets the timer 'mytimer' to beep once every hour on Tuesdays
  2793.     setalarm 'mytimer'
  2794.        -1               // any year
  2795.        -1               // any month
  2796.        -1               // any day
  2797.         2               // only on Tuesdays
  2798.        -1               // any hour
  2799.         0               // only at zero minutes past the hour
  2800.         0               // only at zero seconds past zero minutes
  2801.        ''               // dispatch in the current event object
  2802.        'beep' 700 300   // execute the function call 'beep 700 300'
  2803.  
  2804.  
  2805.   The following is a complete list of the builtin timer functions:
  2806.  
  2807.     destroytimer   // destroys a timer
  2808.     setalarm       // sets an alarm timer
  2809.     setrepeat      // sets a repeating interval timer
  2810.     settimer       // sets a non-repeating interval timer
  2811.     timer?         // tests for the existence of a timer
  2812.  
  2813.  
  2814.   Windows
  2815.   ───────
  2816.   A window is a rectangular area of the screen used to display buffers,
  2817.   simple video output, or other child windows.
  2818.  
  2819.   If a window displays a buffer, it must be associated with a specific
  2820.   cursor in the buffer. Since a buffer may contain many cursors,
  2821.   multiple windows may be used to display different areas of the same
  2822.   buffer.
  2823.  
  2824.   The editor maintains an internal list of windows called the 'window
  2825.   list', with the 'current' window as the first window in the list. Each
  2826.   window is identified by a unique 'windowid'. Not specifying a windowid
  2827.   (or specifying a null windowid) for many of the builtin window
  2828.   functions usually indicates that the 'current' window should be used.
  2829.  
  2830.   There are many builtin functions which can be used to manipulate
  2831.   windows. The most important functions are discussed briefly here. Many
  2832.   of these functions can be specified with several arguments, but are
  2833.   shown here in their simplest forms.
  2834.  
  2835.   To create and destroy windows, use the 'createwindow' and
  2836.   'destroywindow' functions:
  2837.  
  2838.     createwindow
  2839.       .
  2840.       <set the window appearance>
  2841.       .
  2842.       <display items in the window>
  2843.       .
  2844.     destroywindow
  2845.  
  2846.   Once a window has been created, there are several functions which can
  2847.   be used to change detailed aspects of the windows appearance.
  2848.  
  2849.   When a window is initially created, it is just a simple rectangle
  2850.   covering the entire screen. The 'setframe' function adds or removes
  2851.   window 'frame components'. Frame components are features in the window
  2852.   frame such as borders, title bars, and menu bars. For example:
  2853.  
  2854.     createwindow     // create a new window
  2855.     setframe 'bn'    // add borders and north title bar to the window
  2856.  
  2857.   Borders are initially created with a thickness of zero, so the
  2858.   'setborder' function should be used to set the border thickness and
  2859.   style:
  2860.  
  2861.     setborder '1'    // use border style '1' (default thickness = 1)
  2862.  
  2863.   Since a title bar was specified in the 'setframe' function call, you
  2864.   will probably want to set the window title using the 'settitle'
  2865.   function:
  2866.  
  2867.     settitle "Hello World!"
  2868.  
  2869.   You can also add window controls and a shadow with the 'setwinctrl'
  2870.   and 'setshadow' functions:
  2871.  
  2872.     setwinctrl '≡'   // add a 'close' icon
  2873.     setshadow 2 1    // set the shadow thickness
  2874.  
  2875.   You may wish also wish to change the window colors by using the
  2876.   'setcolor' function:
  2877.  
  2878.     setcolor  border1_color      color white on gray   // border color
  2879.     setcolor  text_color         color black on gray   // text color
  2880.     setcolor  north_title_color  color white on green  // title color
  2881.  
  2882.   Finally, you can change the size and/or position of the window
  2883.   using the 'sizewindow' function:
  2884.  
  2885.     sizewindow 6 5 72 20 'ad'   // size window relative to the screen
  2886.  
  2887.   Now that the window has been created and styled to your preferences,
  2888.   you will probably want to display something in the window 'client
  2889.   area'. The client area is the main area in the middle of the window
  2890.   which is not part of the borders, menus, or titles.
  2891.  
  2892.   If you are using the window for simple video output, the 'writestr'
  2893.   and 'writeline' functions can be used to display strings in the window
  2894.   client area, and the 'gotoxy' function can be used to change the
  2895.   position of the video cursor:
  2896.  
  2897.     writestr "A string"    // write a string
  2898.     gotoxy 5 2             // go to column 5, row 2 in the window
  2899.  
  2900.     writeline "A line and a carriage return"
  2901.       // write a string with a carriage return,
  2902.       //   scrolling the window if needed
  2903.  
  2904.   Note that this window does not display a buffer. The cursor is a
  2905.   simple video cursor, not the type of cursor associated with a buffer
  2906.   (see 'Cursors').
  2907.  
  2908.   Since the video cursor is still hidden at this point, you may wish to
  2909.   display it with the 'showcursor' function:
  2910.  
  2911.     showcursor 80 90   // display the cursor near the bottom of the
  2912.                        //   character cell
  2913.  
  2914.   As you are writing text to the client area, you can use the 'display'
  2915.   function to force the editor to update the display before continuing:
  2916.  
  2917.     writeline "a line"              // write some lines
  2918.     writeline "another line"
  2919.     display                         // update the display
  2920.     writeline "yet another line"
  2921.  
  2922.   To display a buffer in a window, the video window functions described
  2923.   above (writestr, writeline, gotoxy) are not sufficient. Buffers are
  2924.   displayed in a window by first creating a cursor for the buffer and
  2925.   then attaching the cursor to a window by using the 'setwincurs'
  2926.   function. For example:
  2927.  
  2928.     cursor = createcursor  // create a cursor for the current buffer
  2929.     setwincurs cursor      // attach the cursor to the current window
  2930.  
  2931.   Once this connection has been established, any changes made to the
  2932.   cursor or the buffer will be displayed automatically in the window the
  2933.   next time the editor becomes idle. The 'display' function can still be
  2934.   used to force the editor to update the display as changes are being
  2935.   made to the buffer or the cursor. For example:
  2936.  
  2937.     writetext "Some text"        // enter text in the buffer
  2938.     display                      // show the text
  2939.     writetext "Some more text"   // enter more text, but don't display
  2940.                                  //   it until the editor becomes idle
  2941.  
  2942.   Windows which display buffers can also be scrolled. The following is a
  2943.   complete list of the builtin scrolling functions:
  2944.  
  2945.     adjustcol    // adjust left window view offset
  2946.     adjustrow    // adjust top window view offset
  2947.     pagedown     // scroll down one page
  2948.     pageup       // scroll up one page
  2949.     rollcol      // scroll left or right by a relative amount
  2950.     rollrow      // scroll up or down by a relative amount
  2951.     scrollcol    // scroll directly to a column
  2952.     scrollrow    // scroll directly to a row
  2953.  
  2954.   A window can be associated with an event-handling object by using the
  2955.   'setwinobj' function:
  2956.  
  2957.     setwinobj "edit"
  2958.       // associate the current window with the 'edit' object
  2959.  
  2960.   When a window has been associated with an event-handling object, the
  2961.   current event object will be automatically set to that object whenever
  2962.   the window becomes the current window. In this way, an entire set of
  2963.   keyboard and mouse event handling functions are associated with a
  2964.   particular window or window type. The event-handling object becomes,
  2965.   in effect, the 'window class'.
  2966.  
  2967.   For example in the default editor setup, edit windows are associated
  2968.   with the 'edit' object and file manager windows are associated with
  2969.   the 'fmgr' object. When you switch between edit and file manager
  2970.   windows, the current event object is automatically changed, resulting
  2971.   in different keyboard and mouse behaviour for each window.
  2972.  
  2973.   The 'wintype?' builtin function can be used to test the entire
  2974.   inheritance hierarchy or 'object ancestry' associated with a window.
  2975.   For example:
  2976.  
  2977.     // test if the event-handling object associated with the
  2978.     //   the current window is descended from the 'edit' object
  2979.     //   (or put more simply, 'is this an edit window?')
  2980.     if wintype? 'edit' then 
  2981.       .
  2982.       <do only for edit windows>
  2983.       .
  2984.     end 
  2985.  
  2986.  
  2987.   The following is a complete list of the window functions:
  2988.  
  2989.     builtin functions:
  2990.       createwindow   // create a new window
  2991.       destroywindow  // destroy a window
  2992.       display        // update the display
  2993.       eotstring      // change the 'end-of-text' line in a window
  2994.       frame?         // test for window frame components
  2995.       getborder      // get window border information
  2996.       getbotwin      // get the windowid of the bottommost window
  2997.       getchild       // get a child windowid
  2998.       getcolor       // get window colors
  2999.       getcoord       // get window dimensions and coordinates
  3000.       getcurrwin     // get the windowid of the topmost window
  3001.       getnextwin     // get the windowid of the next window
  3002.       getparent      // get a parent windowid
  3003.       getprevwin     // get the windowid of the previous window
  3004.       getregion      // get a window region from virtual coordinates
  3005.       gettitle       // get a window title
  3006.       getviewbot     // get the bottommost visible row in window
  3007.       getviewcols    // get the visible window width
  3008.       getviewleft    // get the leftmost column in window
  3009.       getviewright   // get the rightmost visible column in window
  3010.       getviewrows    // get the visible window height
  3011.       getviewtop     // get the topmost row in a window
  3012.       getwinbuf      // get the bufferid associated with a window
  3013.       getwincount    // get the number of windows or child windows
  3014.       getwinctrl     // get a title bar control
  3015.       getwincurs     // get the cursorid attached to a window
  3016.       getwinobj      // get object name associated with a window
  3017.       getwinscr      // get a scroll bar position from virtual coords
  3018.       gotowindow     // change the default window for builtin functions
  3019.       hidecursor     // hide a cursor (temporarily for buffer windows)
  3020.       hidewindow     // hide a window temporarily
  3021.       hilite         // highlight text in a window
  3022.       movewindow     // move a window to a new location
  3023.       setborder      // change the window borders
  3024.       setcolor       // change the window colors
  3025.       setframe       // add or remove window frame components
  3026.       setnextwin     // set the next window
  3027.       setparent      // set the parent window
  3028.       setprevwin     // set the previous window
  3029.       setshadow      // set the window shadow
  3030.       setshadow2     // set the 1/2 window shadow
  3031.       settitle       // change a window title
  3032.       setwinctrl     // define window title bar controls
  3033.       setwincurs     // attach a cursor (and a buffer) to a window
  3034.       setwinobj      // associate a window with an object
  3035.       showcursor     // show a cursor
  3036.       showwindow     // show a hidden window
  3037.       sizewindow     // change the size of a window
  3038.       tilewindow     // tile windows
  3039.       virtocol       // convert a virtual X-coordinate to a column
  3040.       virtorow       // convert a virtual Y-coordinate to a row
  3041.       window?        // test for the existence of a window
  3042.       wintype?       // test the window event object hierarchy
  3043.  
  3044.       Note: the following builtin functions are only meaningful in video
  3045.       output windows (windows which do not display a buffer):
  3046.  
  3047.       clearwindow    // clear the contents of a video window
  3048.       getx           // get the column of video window cursor
  3049.       gety           // get the row of video window cursor
  3050.       gotoxy         // move the cursor of video window
  3051.       writeline      // display a string and CR in a video window
  3052.       writestr       // display a string in a video window
  3053.  
  3054.     library functions:
  3055.       cascade        // cascade all windows
  3056.       copywin        // copy the current edit window
  3057.       currwin        // change the current window
  3058.       deletewin      // delete the current window
  3059.       getsettings    // get the current window settings
  3060.       max?           // test if the current window is maximized
  3061.       maximize       // maximize the current window
  3062.       min?           // test if the current window is minimized
  3063.       minimize       // minimize the current window
  3064.       nextwindow     // switch to the next window
  3065.       pankey         // pan the video background with the keyboard
  3066.       prevwindow     // switch to a previous window
  3067.       restore        // restore the current window
  3068.       setdraw        // set the window line-drawing style
  3069.       setting        // change a window setting
  3070.       setting?       // test if specified window settings are ON
  3071.       sizekey        // resize or move the current window with the kbd
  3072.       sizewin        // resize or move the current window
  3073.       splitwin       // split the current edit window
  3074.       tile           // tile all windows horizontally or vertically
  3075.       togglestyle    // toggle the style of the current window
  3076.       toolbar        // display a toolbar on the current window
  3077.       winlist        // display a popup menu of open windows
  3078.  
  3079.  
  3080.   Video Functions
  3081.   ───────────────
  3082.   Several functions are provided which allow you to control certain
  3083.   characteristics of the video device or retrieve information about the
  3084.   current state of the video device.
  3085.  
  3086.   When viewing the editor, the display device is only a small window
  3087.   into the 'virtual' screen actually used by the editor. Although your
  3088.   screen may only display 80 columns by 25 rows at one time, the size of
  3089.   the virtual screen is actually 64000 x 64000 characters.
  3090.  
  3091.   When the editor is initially started, the physical display device is
  3092.   located at column 16000 and row 16000 of the virtual screen. You can
  3093.   adjust this mapping of the physical screen to the virtual screen by
  3094.   using the 'pan' and 'panto' builtin functions:
  3095.  
  3096.     pan 10 -2           // pan right 10 columns, up 2 rows
  3097.     panto 17000 17000   // pan to virtual screen location 17000,17000
  3098.  
  3099.   You can use the 'videomode' library function to change the video mode:
  3100.  
  3101.     videomode 80 50     // set the video mode to 80 x 50
  3102.     videomode 80 28     // set the video mode to 80 x 28
  3103.  
  3104.   To write text on the screen background, use the 'writebak' function:
  3105.  
  3106.     writebak "The date is: " + getdate  2 2 color black on gray
  3107.       // writes the date on the screen background at column 2 row 2
  3108.       //   relative to the upper left corner of the screen, using
  3109.       //   the color 'black on gray'
  3110.  
  3111.   The following is a complete list of the video functions:
  3112.  
  3113.     builtin functions:
  3114.       blink         // enable or disable the video blink mode
  3115.       getpalette    // return a color attribute or the entire palette
  3116.       getvidbot     // return the bottom edge of the virtual screen
  3117.       getvidcols    // return the screen width
  3118.       getvidleft    // return the left edge of the virtual screen
  3119.       getvidright   // return the right edge of the virtual screen
  3120.       getvidrows    // return the screen height
  3121.       getvidtop     // return the top edge of the virtual screen
  3122.       mono?         // test for a monochrome display
  3123.       pan           // pan the virtual screen (relative)
  3124.       panto         // pan the virtual screen (absolute)
  3125.       setdisplay    // enable/disable display updating
  3126.       setpalette    // define the color palette
  3127.       setvideo      // change video mode/background
  3128.       showentry     // show the entry screen when the editor was started
  3129.       videoborder   // change the video overscan border color
  3130.  
  3131.     library functions:
  3132.       videomode     // change the video mode
  3133.  
  3134.     extension functions:
  3135.       togglemode    // toggle the video mode between 80x25 and 80x50
  3136.  
  3137.  
  3138.   Syntax Highlighting
  3139.   ───────────────────
  3140.   Syntax Highlighting is an editor feature which automatically colors
  3141.   characters, words, and phrases in a buffer when the buffer is
  3142.   displayed in a window. This feature can be used to highlight the
  3143.   source code of many different programming languages, or even text
  3144.   files. Using a few simple functions and statements, you can easily
  3145.   configure how elements in your text are highlighted.
  3146.  
  3147.   To specify how you would like your text to be highlighted, a syntax
  3148.   highlighting object must first be defined. A syntax highlighting
  3149.   object is created with the 'object' statement, in the same way as
  3150.   other objects are created. The 'syntax' function is then called within
  3151.   the object to create a syntax highlighting 'template' for the object.
  3152.   The template specifies highlighting options, syntax elements to be
  3153.   highlighted, and highlighting colors. For example:
  3154.  
  3155.     // syntax highlighting object for AML
  3156.     object aml
  3157.  
  3158.       syntax
  3159.  
  3160.         // syntax highlighting options
  3161.         'bin'                           // b=show through marked block
  3162.                                         // c=don't highlight cursor line
  3163.                                         // i=ignore keyword case
  3164.                                         // n=highlight numbers
  3165.  
  3166.         // language elements to be highlighted
  3167.         '()=+-*/<>|&^,[]:'              // symbol set
  3168.         '"\''                           // string characters
  3169.         '\\'                            // string literal char
  3170.         ''                              // numeric char
  3171.         '//'          0                 // eol comment 1 / start column
  3172.         ''            0                 // eol comment 2 / start column
  3173.         '/*'          '*/'              // multi-line comment 1
  3174.         ''            ''                // multi-line comment 2
  3175.         0                               // number of lines to scan backward
  3176.  
  3177.         // colors
  3178.         color brightcyan   on blue      // keyword color
  3179.         color gray         on blue      // symbol color
  3180.         color brightred    on blue      // string color
  3181.         color brightred    on blue      // numeric color
  3182.         color brightgreen  on blue      // eol1 comment color
  3183.         color yellow       on blue      // eol2 comment color
  3184.         color brightgreen  on blue      // comment1 color
  3185.         color brightcyan   on blue      // comment2 color
  3186.  
  3187.   (see the 'syntax' function in the AML Function Reference for a
  3188.   description of syntax parameters).
  3189.  
  3190.   To define keywords to be highlighted, use the 'keyword' statement
  3191.   within the syntax highlighting object:
  3192.  
  3193.     object aml
  3194.         .
  3195.         .
  3196.       // define AML keywords to highlight
  3197.       keyword 
  3198.         if, then, else, elseif, if?, case, when, otherwise, function,
  3199.         set, setobj, setx, setxobj, object, while, do, repeat, until,
  3200.         .
  3201.         .
  3202.  
  3203.   Keywords do not need to be entered in any specific order.
  3204.  
  3205.   Syntax highlighting keywords are actually stored as object variables
  3206.   in the syntax highlighting object. The value of the object is the
  3207.   keyword color, or zero if the color specified in the template is to be
  3208.   used. This allows you to dynamically assign different colors to
  3209.   individual keywords, or define new keywords on-the-fly. For example:
  3210.  
  3211.     // change the color of the keywords 'if' and 'then'
  3212.     // from the default template color
  3213.     _if    = color white on green
  3214.     _then  = color white on brightred
  3215.  
  3216.     // add a new keyword from within a macro
  3217.     _myvar = color white on magenta
  3218.  
  3219.  
  3220.   The 'setsyntax' statement associates or disassociates a syntax
  3221.   highlighting object with a window. For example:
  3222.  
  3223.     // attach the AML syntax highlighting object to the current window
  3224.     // and turn it ON.
  3225.     setsyntax ON "aml"
  3226.  
  3227.  
  3228.   The following is a complete listing of the syntax highlighting
  3229.   functions and statements:
  3230.  
  3231.     statements:
  3232.       keyword      // define syntax highlighting keywords
  3233.  
  3234.     builtin functions:
  3235.       setsyntax    // enable or disable syntax highlighting for a window
  3236.       syntax       // define a syntax highlighting template for the
  3237.                    //   current object
  3238.  
  3239.     extension functions:
  3240.       onsyntax     // called by the editor library (LIB.X) to get the
  3241.                    //   syntax highlighting object for a filename
  3242.       hiliteword   // dynamically define the word at the cursor as
  3243.                    //   a syntax highlighting keyword
  3244.  
  3245.  
  3246.   File Handling Functions
  3247.   ───────────────────────
  3248.   The macro language provides many useful functions for manipulating
  3249.   files on disk, and for retrieving path and drive information. A few of
  3250.   these functions are discussed briefly here.
  3251.  
  3252.   To convert a filename to a fully-qualified filename, use the 'qualify'
  3253.   function:
  3254.  
  3255.     qualify "file.txt"
  3256.       // returns C:\FILE.TXT if C:\ is the current path
  3257.     qualify "file.txt" "e:\\doc\\abc.doc"
  3258.       // returns E:\DOC\FILE.TXT
  3259.  
  3260.   The 'locatefile' function can be use to search a directory or path for
  3261.   a file:
  3262.  
  3263.     locatefile "FILE.TXT" (getenv "PATH")
  3264.       // returns FILE.TXT (fully qualified), if FILE.TXT is
  3265.       //   found in the DOS PATH
  3266.  
  3267.   To retrieve different parts of a filename, use the 'getpath',
  3268.   'getname', and 'getext' functions:
  3269.  
  3270.     getpath "d:\\aurora\\kbd.aml"   // returns 'd:\aurora\'
  3271.     getname "d:\\aurora\\kbd.aml"   // returns 'kbd.aml'
  3272.     getext  "d:\\aurora\\kbd.aml"   // returns '.aml'
  3273.  
  3274.  
  3275.   The following is a complete list of the file handling functions:
  3276.  
  3277.     builtin functions:
  3278.       bootpath       // get a filename in terms of the editor bootpath
  3279.       chgfileattr    // change file attributes
  3280.       closefile      // close an open file
  3281.       copyfile       // copy a file
  3282.       createdir      // create a new directory
  3283.       currpath       // change the current drive and/or path
  3284.       deletefile     // delete a file
  3285.       fileattr?      // test file attributes
  3286.       filepos        // change the position in an open file
  3287.       getbootpath    // get the editor invocation path
  3288.       getcurrpath    // get the current DOS path
  3289.       getdisk        // get disk drive information
  3290.       locatefile     // search for a file or directory in a path
  3291.       openfile       // open a file and return a file handle
  3292.       qualify        // get a fully qualified filename
  3293.       readfile       // read from an open file
  3294.       renamefile     // rename a file
  3295.       scanfile       // scan a file for a string
  3296.       setbootpath    // change the bootpath
  3297.       touchfile      // update the date and time of a file
  3298.       writefile      // write to an open file
  3299.  
  3300.     library functions:
  3301.       dir?           // test if a filespec is a directory
  3302.  
  3303.     extension functions:
  3304.       defext         // append a default extension if no extension
  3305.       forceext       // force a filename to have an extension
  3306.       getext         // get the extension portion of a filespec
  3307.       getname        // get the name & extension portion of a filespec
  3308.       getpath        // get the drive & path portion of a filespec
  3309.  
  3310.  
  3311.   System Functions
  3312.   ────────────────
  3313.   The editor also provides builtin functions to control and retrieve
  3314.   information about the operating environment of the editor. These
  3315.   functions control memory usage and printer devices, and return
  3316.   information such as the date and time, environment strings, and
  3317.   version numbers.
  3318.  
  3319.   Some system functions are usually called only once for each edit
  3320.   session:
  3321.  
  3322.     cursorsize     // set the insert and overstrike cursor size
  3323.     international  // define international date and time formats
  3324.     maxems         // define the amount of EMS memory to use
  3325.     maxxms         // define the amount of XMS memory to use
  3326.     memoptions     // set memory usage options
  3327.     printformat    // define the initial printer settings
  3328.     speaker        // enable or disable the PC speaker
  3329.     swapfiles      // define the swapfiles to use
  3330.  
  3331.   Other system functions return information about the operating
  3332.   environment:
  3333.  
  3334.     getenv         // return the value of a DOS environment variable
  3335.     getexe         // return the editor .EXE file name
  3336.     getos          // return the operating system version
  3337.     getversion     // return the current version of the editor
  3338.  
  3339.     getrawtime     // return the time and date in raw format
  3340.     getdate        // return the date in international format
  3341.     gettime        // return the time in international format
  3342.  
  3343.  
  3344.   The Keyboard
  3345.   ────────────
  3346.   When a key is pressed on the keyboard, the editor will generally
  3347.   respond by calling a user defined event-handling function accessible
  3348.   from within the current event object. For example:
  3349.  
  3350.     // move the cursor to the top line when <ctrl x> is pressed
  3351.     key <ctrl x>
  3352.       row 1
  3353.     end 
  3354.  
  3355.   The keycode is passed as the first argument:
  3356.  
  3357.     // display the keycode for <ctrl x>
  3358.     key <ctrl x> (keycode)
  3359.       say "The keycode for <ctrl x> is: " + keycode
  3360.     end 
  3361.  
  3362.   The event-handling function names for most keyboard function keys
  3363.   (<ctrl x>, <shift f3>, etc.) are predefined within the editor (see
  3364.   'Appendix A: Key Event Names').
  3365.  
  3366.   When any shift key is pressed (<shift>, <ctrl>, <scroll lock>, etc.),
  3367.   the editor will call the '<shiftkey>' event-handling function, passing
  3368.   the old keyboard shift state and the new keyboard shift state.
  3369.  
  3370.   When a single character, non-function key such as 'a', or 'Z' is
  3371.   entered, the editor will call the '<char>' event-handling function,
  3372.   passing the character entered as the first argument and the keycode as
  3373.   the second argument. For example:
  3374.  
  3375.     // insert non-function keys into the buffer at the cursor
  3376.     key <char> (character keycode)
  3377.       writetext character
  3378.     end 
  3379.  
  3380.   If the editor attempts to dispatch a keyboard event, but does not find
  3381.   an event-handling function for the event within the current event
  3382.   object (or within the object hierarchy), the editor will call the
  3383.   default function '<otherkey>', passing the keycode of the key entered.
  3384.   For example:
  3385.  
  3386.     // undefined keys
  3387.     key <otherkey> (keycode)
  3388.       say (getkeyname (keycode)) + " not defined"
  3389.     end 
  3390.  
  3391.   The '<otherkey>' event-handling function can also be used to respond
  3392.   to special hardware-specific keycodes for which the editor has no
  3393.   predefined names.
  3394.  
  3395.   When any shift key (<shift>, <ctrl>, <scroll lock>, etc.) is pressed
  3396.   or released, the editor will call the '<shiftkey>' event-handling
  3397.   function, passing the old keyboard shift state and the new keyboard
  3398.   shift state. The old and new shift states can be compared by the
  3399.   event-handling function to determine what shift key event actually
  3400.   occurred (see the 'shiftkey?' function in the AML Function Reference
  3401.   for a description of the shift state). For example:
  3402.  
  3403.     key <shiftkey> (newstate oldstate)
  3404.       if newstate & 3 and not (oldstate & 3) then 
  3405.         send "shiftdown"
  3406.       elseif oldstate & 3 and not (newstate & 3) then 
  3407.         send "shiftup"
  3408.       end 
  3409.     end 
  3410.  
  3411.  
  3412.   By default, the inheritance hierarchy of an object is searched
  3413.   whenever a keyboard event-handling function is not found in the
  3414.   object. The 'inheritkeys' function can be used to enable or disable
  3415.   the inheritance of keyboard events in the object in which it is
  3416.   called. For example:
  3417.  
  3418.     object abc
  3419.       inheritkeys OFF  // turn off kbd inheritance in object 'abc'
  3420.  
  3421.   'inheritkeys' can be used by an object to temporarily block parent
  3422.   objects from handling any keyboard events.
  3423.  
  3424.   Whenever possible, user-defined event-handling functions (as shown
  3425.   above) should be used to respond to keyboard events. However, it is
  3426.   sometimes necessary to wait for a keypress from within a macro. The
  3427.   'getkey' function waits for the next key and returns the keycode for
  3428.   the key pressed. For example:
  3429.  
  3430.     keycode = getkey
  3431.     if keycode == <ctrl x> then 
  3432.       row 1
  3433.     end 
  3434.  
  3435.   If the mouse is clicked while getkey is waiting for a key, the keycode
  3436.   '<button>' is returned. Note that 'getkey' should be used only in
  3437.   situations where an event-handling function will not be sufficient,
  3438.   since it will prevent other events from being dispatched.
  3439.  
  3440.   The 'getkeyname' and 'getkeycode' functions can be used to get the
  3441.   event-handling function name associated with a keycode, and vice
  3442.   versa. For example:
  3443.  
  3444.     keycode = getkey               // wait for a key
  3445.     keyname = getkeyname keycode   // get the keyname for the keycode
  3446.     keycode = getkeycode keyname   // doesn't change 'keycode'
  3447.  
  3448.   The 'sendkey' and 'queuekey' functions can be used to execute the
  3449.   event-handling functions associated with keycodes:
  3450.  
  3451.     keycode = getkey   // wait for a key and get a keycode
  3452.     sendkey keycode    // dispatch the key immediately
  3453.     queuekey keycode   // queue the key
  3454.  
  3455.   To test the current shift-state of the keyboard, use the 'shiftkey?'
  3456.   function. For example:
  3457.  
  3458.     // test if the left or right <shift> keys are down
  3459.     if shiftkey? then 
  3460.       .
  3461.       .
  3462.     end 
  3463.  
  3464.     // test if scroll-lock is ON
  3465.     if shiftkey? 10h then 
  3466.       .
  3467.       .
  3468.     end 
  3469.  
  3470.  
  3471.   The following is a complete list of the keyboard functions:
  3472.  
  3473.     builtin functions:
  3474.       enhancedkbd    // enable or disable the enhanced keyboard keys
  3475.       getkey         // wait for a key and return a keycode
  3476.       getkeycode     // get a keycode for keyname
  3477.       getkeyname     // get a keyname for a keycode
  3478.       inheritkeys    // enable or disable keyboard event inheritance
  3479.       keyhit?        // test if a key was pressed
  3480.       queuekey       // push keycode(s) onto the event queue
  3481.       sendkey        // execute keycode(s) immediately
  3482.       shiftkey?      // test the shift key state
  3483.  
  3484.     extension functions:
  3485.       askrepkey      // prompt to repeat a key or keys
  3486.       prefix         // generate multi-key events
  3487.  
  3488.  
  3489.   The Mouse
  3490.   ─────────
  3491.   Several functions are provided to control the operation of the mouse
  3492.   within the editor. To use the mouse, a DOS mouse driver must have been
  3493.   successfully installed before the editor is started.
  3494.  
  3495.   In order for mouse events to be processed on the event queue, the
  3496.   mouse must be initialized with the 'openmouse' function when the
  3497.   editor is started. The 'closemouse' function should be called when
  3498.   exiting the editor:
  3499.  
  3500.     openmouse
  3501.       .
  3502.       .
  3503.       .
  3504.     closemouse
  3505.  
  3506.   If the mouse is successfully opened, and the mouse is moved or mouse
  3507.   buttons are clicked, the editor will call a user-defined function
  3508.   associated with the mouse event in the current event object. For
  3509.   example:
  3510.  
  3511.     // respond to a left mouse button click
  3512.     function <lbutton>
  3513.       say "you pressed the left mouse button"
  3514.     end 
  3515.  
  3516.   The event-handling function names for mouse events (such as <lbutton>,
  3517.   <lbuttonup>, etc.) are predefined within the editor (see Appendix B:
  3518.   Mouse Event Names).
  3519.  
  3520.   The coordinates of the mouse pointer on the virtual screen can be
  3521.   obtained from the 'getmousex' and 'getmousey' functions. For example:
  3522.  
  3523.     // respond to a left mouse button click
  3524.     function <lbutton>
  3525.       say "Mouse x coordinate is: " + getmousex +
  3526.           "Mouse y coordinate is: " + getmousey
  3527.     end 
  3528.  
  3529.   To find out what window 'region' the mouse pointer is located in, use
  3530.   the 'getregion' function:
  3531.  
  3532.     // respond to a left mouse button click
  3533.     function <lbutton>
  3534.       case getregion
  3535.         when  0  say "not in the window"
  3536.         when  1  say "client area"
  3537.         when 11  say "north title bar"
  3538.         otherwise say "other window region"
  3539.       end 
  3540.     end 
  3541.  
  3542.   The 'virtocol' and 'virtorow' functions are useful for determining the
  3543.   buffer column and row where the mouse pointer is located. For example:
  3544.  
  3545.     // respond to a left mouse button click
  3546.     function <lbutton>
  3547.       say "you clicked on column " + (virtocol (getmousex)) +
  3548.           ", row " +                 (virtorow (getmousey))
  3549.     end 
  3550.  
  3551.   To find out if a mouse button is being held down, use the 'button?'
  3552.   function:
  3553.  
  3554.     if button? 2h then  // is the right mouse button down?
  3555.       .
  3556.       .
  3557.     end 
  3558.  
  3559.  
  3560.   The following is a complete list of the mouse functions:
  3561.  
  3562.     builtin functions:
  3563.       button?        // test the mouse button state
  3564.       closemouse     // disable the mouse
  3565.       getmousex      // get the mouse virtual X coordinate
  3566.       getmousey      // get the mouse virtual Y coordinate
  3567.       getregion      // get the window region at the mouse position
  3568.       hidemouse      // hide the mouse cursor
  3569.       mousepos       // change the mouse pointer position
  3570.       mousesense     // change the mouse sensitivity
  3571.       openmouse      // enable the mouse
  3572.       showmouse      // show the mouse cursor
  3573.       virtocol       // convert a virtual X coordinate to a column
  3574.       virtorow       // convert a virtual Y coordinate to a row
  3575.  
  3576.     library functions:
  3577.       trackmouse     // move the cursor to the mouse pointer position
  3578.  
  3579.  
  3580.   Menus
  3581.   ─────
  3582.   Menus are windows (or window regions) which allow you to select an
  3583.   item from a list of choices. The selected item may be a number, a
  3584.   string, or even macro code to be executed when the item is selected.
  3585.   Menus can be defined and displayed by using macro language builtin
  3586.   functions and library functions.
  3587.  
  3588.   There are three basic types of menus: menu bars, pull-down menus
  3589.   (associated with menu bars), and independent popup menus.
  3590.  
  3591.   A menu bar can be associated with a window by using the 'menubar'
  3592.   statement. Up to five menu bars can be defined for each window. For
  3593.   example:
  3594.  
  3595.     menubar  '' 1
  3596.       item "&File"     "editFile"
  3597.       item "&Window"   "editWindow"
  3598.       item "&Block"    "editBlock"
  3599.       item "&Search"   "editSearch"
  3600.       item "F&old"     "editFold"
  3601.       item "&Edit"     "editEdit"
  3602.       item "&Clip"     "editClip"
  3603.       item "&Print"    "editPrint"
  3604.       item "Se&t"      "editSet"
  3605.       item "M&acro"    "editMacro"
  3606.       item "&Help"     "editHelp"
  3607.     end 
  3608.  
  3609.   In the example above, a primary menu bar is defined for the current
  3610.   window (if a primary menu bar was already defined for the window, then
  3611.   it is replaced). The first argument after the 'item' keyword is the
  3612.   item description to appear on the menu bar. The '&' character
  3613.   indicates which character in the description is highlighted (and also
  3614.   which is the 'hot key' for that item). Specifying double ampersands
  3615.   '&&' indicates that the window control color should be used to
  3616.   highlight the item (for menu bars only).
  3617.  
  3618.   The second 'argument' after the 'item' keyword is the name of the
  3619.   pull-down menu to be activated when the item is selected. If desired,
  3620.   the second 'argument' can also be one or more macro language
  3621.   expressions to be evaluated in the current event object when the menu
  3622.   bar item is selected.
  3623.  
  3624.   To define a pull-down menu for a menu bar, or to define a popup menu,
  3625.   use the 'menu' statement. For example:
  3626.  
  3627.     menu  "editFile"
  3628.       item " &New                  <ctrl n>"  opennew
  3629.       item " &Open..                <alt e>"  askopen
  3630.       item " Open and &Insert..     <alt i>"  askinsert
  3631.       item " Open &Binary.."                  askopenb
  3632.       item " Open Las&t             <alt z>"  openlast
  3633.       item " &Rename..              <alt n>"  askname
  3634.       item " &Save                     <f3>"  save
  3635.       item " Sa&ve As.."                      asksaveas
  3636.       item "-"
  3637.       item " &File Manager..           <f4>"  open "*.*"
  3638.       item " Ne&xt               <ctrl del>"  nextfile
  3639.       item " &Prev               <ctrl ins>"  prevfile
  3640.       item " &List..                <alt ->"  filelist
  3641.       item "─"
  3642.       item " &Close                 <alt q>"  close
  3643.       item " Close &All             <alt x>"  closeall
  3644.       item " Sav&e and Close       <ctrl x>"  close "s"
  3645.       item " Save an&d Close All"             closeall "s"
  3646.       item "─"
  3647.       item " Abo&ut.."                        about
  3648.     end 
  3649.  
  3650.   In the example above, a pull-down menu 'editFile' is defined for the
  3651.   first menu bar item 'File' in the previous menu bar example. Note that
  3652.   unlike 'menubar', the 'menu' statement will not replace an existing
  3653.   menu definition. Menus are actually buffers and must be destroyed with
  3654.   the 'destroybuf' function before the same menu name can be re-used. If
  3655.   the hyphen (-) character is specified in the item statement, then a
  3656.   dividing line is automatically generated for that item. Otherwise, the
  3657.   'item' keyword and arguments are identical to the 'menubar' statement.
  3658.  
  3659.   Submenus can be displayed by calling the 'submenu' function from a
  3660.   pull-down menu item. For example:
  3661.  
  3662.     menu  "editSet"
  3663.        .
  3664.       item " Word &Processing..             "   submenu "WordP"
  3665.        .
  3666.        .
  3667.     end 
  3668.  
  3669.   In the example above, the submenu 'WordP' is displayed when the 'Word
  3670.   Processing' item is selected.
  3671.  
  3672.   Popup menus are defined with the 'menu' statement in exactly the same
  3673.   way as pull-down menus. However, whereas pull-down menus are
  3674.   automatically displayed when a menu bar item is selected, popup menus
  3675.   must be displayed with the library function 'popup'. For example:
  3676.  
  3677.     // displays the menu 'editFile' in a popup window
  3678.     popup "editFile"
  3679.  
  3680.   A menu title, width, and height can also be specified with the 'popup'
  3681.   function:
  3682.  
  3683.     popup "mymenu" "Menu Title" 25 10
  3684.       // displays the menu 'mymenu' with the title 'Menu Title',
  3685.       //   width 25, and height 10
  3686.  
  3687.   The 'popup' function returns the result of evaluating the macro
  3688.   expression associated with the selected menu item.
  3689.  
  3690.   The 'popup' function can also be used to display ordinary buffers in a
  3691.   popup menu by specifying the bufferid as a menu name. For example:
  3692.  
  3693.     buffer = loadbuf "file.txt"    // load a file into a buffer
  3694.     if buffer then 
  3695.       popup buffer "Menu Title"    // display it in a popup menu
  3696.     end 
  3697.  
  3698.   In this case, the 'popup' function returns the line selected in the
  3699.   buffer.
  3700.  
  3701.  
  3702.   The following is a complete list of the menu statements and functions:
  3703.  
  3704.     statements:
  3705.       menu         // define a pull-down or popup menu
  3706.       menubar      // define a menu bar for a window
  3707.  
  3708.     builtin functions:
  3709.       getmenu      // get menu information
  3710.       getmenubar   // get menu bar information
  3711.       hilitebar    // highlight menu bar item
  3712.  
  3713.     library functions:
  3714.       gotobar      // highlight a menu bar item
  3715.       gotobar2     // highlight a toolbar or drive menu item
  3716.       gotomenu     // display a pull-down menu
  3717.       popup        // display a popup menu
  3718.       submenu      // display a submenu
  3719.  
  3720.  
  3721.   The Desktop
  3722.   ───────────
  3723.   The editor provides several functions for saving and restoring the
  3724.   window layout on the screen. This layout is referred to as the
  3725.   'desktop'. The 'current desktop' refers to an internal representation
  3726.   of a desktop used by these functions.
  3727.  
  3728.   To save the desktop to a file, use the 'currdesk' and 'savedesk'
  3729.   functions:
  3730.  
  3731.     // set the 'current desktop' to the window layout on the screen
  3732.     currdesk
  3733.  
  3734.     // save the current desktop to C:\DESKTOP.BIN
  3735.     savedesk "c:\\desktop.bin"
  3736.  
  3737.   The 'opendesk' and 'restoredesk' functions can restore a previously
  3738.   saved desktop:
  3739.  
  3740.     // set the 'current desktop' to the desktop saved in C:\DESKTOP.BIN
  3741.     opendesk "c:\\desktop.bin"
  3742.  
  3743.     // set the window layout on the screen to the current desktop
  3744.     restoredesk
  3745.  
  3746.  
  3747.   The following is a complete list of the desktop functions:
  3748.  
  3749.     library functions:
  3750.       begdesk       // mark the beginning of the current desktop
  3751.       currdesk      // set the current desktop to the window layout
  3752.       enddesk       // mark the end of the current desktop
  3753.       opendesk      // load a desktop and make it the current desktop
  3754.       openhistory   // load history buffers and the current desktop
  3755.       restoredesk   // set the window layout to the current desktop
  3756.       savedesk      // save the current desktop to a file
  3757.       savehistory   // save all history buffers and the current desktop
  3758.  
  3759.  
  3760.   Prompts and Dialog Boxes
  3761.   ────────────────────────
  3762.   In addition to the menus, the editor provides several useful library
  3763.   and extension functions which allow you to obtain input from the user,
  3764.   and to display messages.
  3765.  
  3766.   To display a simple message on the main window title bar, use the
  3767.   'say' function:
  3768.  
  3769.     say "Hello World!"
  3770.  
  3771.   The message will remain on the title bar until the title bar or status
  3772.   line is updated.
  3773.  
  3774.   To display a message in a message box, use the 'msgbox' and 'shortbox'
  3775.   functions:
  3776.  
  3777.     // display a simple message box with an 'Ok' button
  3778.     msgbox "Hello World!" "Optional Title"
  3779.  
  3780.     // display a simple message box without an 'Ok' button
  3781.     shortbox "Hello World!"
  3782.  
  3783.   The 'okbox' and 'yncbox' functions can be used to display an Ok-Cancel
  3784.   or a Yes-No-Cancel message box. These functions return the text of the
  3785.   selected button, or null if nothing was selected:
  3786.  
  3787.     if (okbox "Delete the file?") == 'Ok' then 
  3788.       deletefile file
  3789.     end 
  3790.  
  3791.     case yncbox "Save before exiting?" "Sample Title"
  3792.       when 'Yes'
  3793.         // <save and exit>
  3794.       when 'No'
  3795.         // <exit>
  3796.       otherwise 
  3797.         // <do nothing>
  3798.     end 
  3799.  
  3800.   To prompt the user for a string, use the 'ask' function. The 'ask'
  3801.   function returns the string entered, or null if the prompt was
  3802.   cancelled. If a 'history bufferid' is specified, prompt history is
  3803.   available (and also recorded) within the prompt. For example:
  3804.  
  3805.     // prompt the user for a string
  3806.     string = ask "Enter a string"
  3807.     if string then 
  3808.       say "you entered: " + string
  3809.     end 
  3810.  
  3811.     // prompt the user for a string, using the history buffer "_load",
  3812.     // ..and initialize the prompt with the string 'c:\file.txt'
  3813.     ask "Enter a string" "_load" "c:\\file.txt"
  3814.  
  3815.   Note that when the user is working within a prompt generated with the
  3816.   'ask' function, the 'prompt' object is the current object. Thus, you
  3817.   can customize the behaviour of a prompt by specifying your own
  3818.   keyboard and mouse event-handling functions within the 'prompt'
  3819.   object.
  3820.  
  3821.   To prompt the user with a simple file selection picklist, use the
  3822.   'askfile' or 'picklist' functions. These functions return the file
  3823.   name (fully qualified) which was selected:
  3824.  
  3825.     file = picklist "*.*"
  3826.     if file then 
  3827.       open file
  3828.       .
  3829.       .
  3830.     end 
  3831.  
  3832.  
  3833.   The following is a complete list of the prompt and dialog box
  3834.   functions:
  3835.  
  3836.     library functions:
  3837.       about         // display an about dialog box
  3838.       ask           // prompt the user for a string
  3839.       askfile       // display a file selection picklist
  3840.       askprint      // display a print settings dialog box
  3841.       finddlg       // display a find dialog box
  3842.       msgbox        // display a message in a window
  3843.       okbox         // display an Ok-Cancel message box
  3844.       repldlg       // display a replace dialog box
  3845.       say           // display a message on the window title bar
  3846.       scandlg       // display a scan dialog box
  3847.       shortbox      // display a message box without an 'Ok' button
  3848.       yncbox        // display a Yes-No-Cancel message box
  3849.  
  3850.     extension functions:
  3851.       asciilist     // display an ASCII chart (with char entry)
  3852.       askrac        // replace/append/cancel popup menu
  3853.       askbinary     // binary line length prompt
  3854.       askc          // generic prompt to change a config variable
  3855.       askcomplete   // filename completion within an open prompt
  3856.       askdelim      // default line delimiter prompt
  3857.       asklmarg      // left margin prompt
  3858.       askprompt     // change the prompt style
  3859.       askprthdr     // change the print header/footer
  3860.       askrmarg      // right margin prompt
  3861.       asktabv       // variable tabs prompt
  3862.       asktabw       // tabwidth prompt
  3863.       askx          // generic prompt (with command execution)
  3864.       picklist      // display a file selection picklist
  3865.  
  3866.  
  3867.   Prompt History
  3868.   ──────────────
  3869.   Prompt history is available within prompts created by the function
  3870.   'ask' when a 'history bufferid' is specified. Prompt history is also
  3871.   available in the edit controls of some dialog boxes (finddlg, repldlg,
  3872.   and scandlg).
  3873.  
  3874.   The 'nexthist' and 'prevhist' functions are used to retrieve the next
  3875.   and previous history strings from within a prompt window:
  3876.  
  3877.     object prompt
  3878.       key <up>      prevhist
  3879.       key <down>    nexthist
  3880.        .
  3881.        .
  3882.  
  3883.   To display a popup menu of all the history strings available in the
  3884.   the current prompt window, use the 'askhistory' function:
  3885.  
  3886.     object prompt
  3887.       key <pgup>    askhistory
  3888.        .
  3889.        .
  3890.  
  3891.   The 'addhistory' function can be used to add a string to a specific
  3892.   history buffer. The history buffer is created if it does not exist.
  3893.   For example:
  3894.  
  3895.     // adds C:\FILE.TXT to the history buffer '_load'
  3896.     addhistory "_load" "C:\\FILE.TXT"
  3897.  
  3898.   The following history buffer names are used by the editor library:
  3899.  
  3900.     _find - search/replace for multi-string prompts
  3901.     _load - fully qualified file names (loading, saving, etc.)
  3902.     _desk - the current desktop
  3903.  
  3904.   The following is a complete list of the prompt history functions
  3905.   available in the editor library (LIB.X):
  3906.  
  3907.     addhistory    // add a string to a history buffer
  3908.     askhistory    // display a history menu for the current prompt
  3909.     gethistname   // get the history buffer for the current prompt
  3910.     gethiststr    // get the most recent string in a history buffer
  3911.     nexthist      // display the next history string in prompt
  3912.     openhistory   // load history buffers and the current desktop
  3913.     pophistory    // display a popup history menu
  3914.     prevhist      // display the previous history string in prompt
  3915.     savehistory   // save all history buffers and the current desktop
  3916.  
  3917.  
  3918.   Primary Editing Functions
  3919.   ─────────────────────────
  3920.   The editor library (LIB.X) and editor extensions (EXT.AML) contain a
  3921.   few important and commonly-used high-level editing functions which are
  3922.   discussed briefly here.
  3923.  
  3924.   To open a file and create a new edit window, or to open a new file
  3925.   manager window, use the 'open' function. For example:
  3926.  
  3927.     open "myfile.txt"        // edit the file 'myfile.txt'
  3928.     open "myfile.txt" 'b'    // edit 'myfile.txt' in binary mode
  3929.     open "myfile.txt" 'i'    // insert 'myfile.txt' at the cursor
  3930.     open "*.txt" 'z'         // open a maximized file manager window
  3931.                              //   displaying the files '*.txt'
  3932.  
  3933.   The 'openbuf' function can be used to display an existing buffer in an
  3934.   edit window. A fully qualified file name should be associated with the
  3935.   buffer by using the 'setbufname' builtin function. For example:
  3936.  
  3937.     prevbuf = getbufname
  3938.     buffer = createbuf ''
  3939.                "first line"
  3940.                "second line"
  3941.     if buffer then 
  3942.       setbufname (qualify "newfile.txt" prevbuf)
  3943.       openbuf buffer
  3944.     end 
  3945.  
  3946.   To save a file in the current edit window, use the 'save' function:
  3947.  
  3948.     save                 // save the file in the current edit window
  3949.     save "c:\\file.txt"  // save the file as 'c:\file.txt'
  3950.  
  3951.   To close the current edit window or file manager window, use the
  3952.   'close' function:
  3953.  
  3954.     close       // close the current window
  3955.     close 's'   // save and close the current edit window
  3956.  
  3957.  
  3958.   The following is a complete list of the primary editing functions:
  3959.  
  3960.     library functions:
  3961.       close       // close the current edit or file manager window
  3962.       filelist    // display a popup menu of open buffers
  3963.       nextfile    // display the next buffer in the current window
  3964.       open        // open a new edit or file manager window
  3965.       openbuf     // display a buffer in an edit window
  3966.       opennew     // open a new edit window with an empty buffer
  3967.       prevfile    // display the previous buffer in the current window
  3968.       reopen      // refresh the current edit or file manager window
  3969.       save        // save the buffer in the current edit window
  3970.       setname     // rename the current edit window and buffer
  3971.  
  3972.     extension functions:
  3973.       askasave    // prompt to set the autosave time interval
  3974.       askinsert   // prompt to insert a file at the cursor
  3975.       askname     // prompt to change the current file name
  3976.       askopen     // prompt to open an edit or file manager window
  3977.       askopenb    // prompt to open a file in binary mode
  3978.       asksaveas   // prompt to save the current file under a new name
  3979.       autosave    // set the autosave time interval
  3980.       close       // close the current window (higher level)
  3981.       closeall    // close all windows
  3982.       opencfg     // open an AML configuration file
  3983.       openlast    // open the last file closed
  3984.       openword    // open the filename at the cursor
  3985.       print       // print current file or marked block
  3986.       printfile   // print a file on disk
  3987.       printstr    // send a string to the printer
  3988.       quickref    // display function reference or quick reference
  3989.  
  3990.  
  3991.   DOS Shell Functions
  3992.   ───────────────────
  3993.   The editor provides several functions for executing DOS programs and
  3994.   batch files from within the editor. All of these functions are based
  3995.   on the low-level builtin function 'exec'. For example:
  3996.  
  3997.     exec "C:\\RUNME.EXE" 'c'
  3998.       // clear the screen and execute "c:\runme.exe"
  3999.  
  4000.     exec "C:\\RUNME.EXE" 'k'
  4001.       // execute "c:\runme.exe" (without clearing the screen),
  4002.       // and prompt the user with a keypress to return
  4003.  
  4004.   The 'os' function changes the current path to the path of the current
  4005.   edit or file manager window before executing the program, and restores
  4006.   the current path after executing the program:
  4007.  
  4008.     os "C:\\RUNME.EXE" 'c'
  4009.       // clear the screen and execute "c:\runme.exe", changing
  4010.       // the current path to the window path
  4011.  
  4012.   The 'shell' function looks for the COMSPEC environment variable to
  4013.   find the location of COMMAND.COM, and then executes COMMAND.COM.
  4014.  
  4015.   Unlike the 'exec' or 'os' functions, the function 'run' will execute
  4016.   DOS commands, programs, and batch files as they would be entered on
  4017.   the DOS command line. It will also search the DOS 'PATH' environment
  4018.   variable if necessary. For example:
  4019.  
  4020.     run "runme" 'c'  // clear the screen and execute 'c:\runme.exe'
  4021.     run "dir" "ck"   // execute the DOS 'dir' command
  4022.  
  4023.  
  4024.   The following is a complete list of the DOS Shell functions:
  4025.  
  4026.     builtin functions:
  4027.       exec       // execute a DOS program (low level)
  4028.  
  4029.     extension functions:
  4030.       askrun     // prompt to execute a DOS command
  4031.       askruncap  // prompt to capture DOS command output
  4032.       os         // execute a DOS program (change and restore path)
  4033.       run        // execute a DOS command
  4034.       runcap     // execute a DOS command and capture output
  4035.       shell      // shell to DOS
  4036.  
  4037.  
  4038.   Key Macro Functions
  4039.   ───────────────────
  4040.   The editor provides several library and extension functions for
  4041.   manipulating 'key macros'. Key macros are recorded sequences of
  4042.   keystrokes which can be played back at a later time.
  4043.  
  4044.   To start and stop recording keystrokes, use the 'setting' function to
  4045.   change the window 'record mode':
  4046.  
  4047.     setting 'R' ON      // start recording keystrokes (record mode ON)
  4048.     setting 'R' OFF     // stop recording keystrokes (record mode OFF)
  4049.     setting 'R' TOGGLE  // toggle the window record mode
  4050.  
  4051.   A key macro that has just been recorded is called the 'scrap' macro.
  4052.   The 'assignkey' function can be used to assign the scrap macro to a
  4053.   key:
  4054.  
  4055.     assignkey   // prompts for a key assignment
  4056.  
  4057.   Both the 'scrap' macro and key-assigned key macros can be executed
  4058.   with the 'playkey' function:
  4059.  
  4060.     playkey            // play the scrap key macro
  4061.     playkey <ctrl m>   // play the key macro assigned to <ctrl m>
  4062.  
  4063.   The 'openkey' and 'savekey' functions are used to save and load all
  4064.   key macros (both the scrap macro and key-assigned macros):
  4065.  
  4066.     savekey "c:\\keymacs.mac"      // save all key macros
  4067.     openkey "c:\\keymacs.mac"      // load saved key macros
  4068.  
  4069.  
  4070.   The following is a complete list of the key macro functions:
  4071.  
  4072.     builtin functions:
  4073.       playing?       // test if a key macro is currently playing
  4074.  
  4075.     library functions:
  4076.       assignkey      // assign the scrap macro to a key
  4077.       erasekey       // erase the scrap macro or all key macros
  4078.       openkey        // load key macros in a file
  4079.       playkey        // execute a key macro
  4080.       savekey        // save all key macros to a file
  4081.       setting        // turn record mode ON and OFF
  4082.  
  4083.     extension functions:
  4084.       askopenkey     // prompt to open a key macro file
  4085.       asksavekey     // prompt to save current key macros
  4086.       erasekey2      // erase key macros (with messages)
  4087.       openkey2       // open a key macro file (with messages)
  4088.       play           // play the current scrap macro
  4089.       record         // toggle the record setting
  4090.  
  4091.  
  4092.   File Manager Functions
  4093.   ──────────────────────
  4094.   Several library and extension functions are provided for interfacing
  4095.   with the file manager.
  4096.  
  4097.   To refresh the contents of the current file manager window, use the
  4098.   'reopen' function:
  4099.  
  4100.     reopen   // refresh the file manager window
  4101.  
  4102.   To retrieve the fully qualified file or directory name at the current
  4103.   line in a file manager window, use the 'getffile' function:
  4104.  
  4105.     deletefile (getffile)   // delete the file at the current line
  4106.     reopen                  // refresh the file manager window
  4107.  
  4108.   To execute a user-defined function for all marked files in the file
  4109.   manager, use the 'fdomark' function. For example:
  4110.  
  4111.     fdomark "chgfileattr" attribute
  4112.  
  4113.   In the above example, the builtin function 'chgfileattr' is called for
  4114.   each marked file, passing the filename as the first argument and the
  4115.   value of the variable 'attribute' as the second argument.
  4116.  
  4117.   The following is a complete list of the file manager functions:
  4118.  
  4119.     library functions:
  4120.       fdobrk     // break out of the 'fdomark' function
  4121.       fdomark    // execute a function for all marked files
  4122.       fmark      // mark or unmark files
  4123.       fmark?     // test if files are marked
  4124.       fscanstr   // get the scan string for a file manager window
  4125.       fsort      // sort files
  4126.       ftype?     // test file manager window type
  4127.       fup        // display the parent directory
  4128.       getffile   // get the filespec at the current line
  4129.       openf      // open files (low level)
  4130.  
  4131.     extension functions:
  4132.       fattr      // change the attributes of a file or marked files
  4133.       fcopy      // copy a file or marked files
  4134.       fdelete    // delete a file or marked files
  4135.       fmkdir     // create a new directory
  4136.       fmove      // move a file or marked files
  4137.       fopen      // open a file or marked files
  4138.       fprint     // print a file or marked files
  4139.       frename    // rename a file or directory
  4140.       frun       // execute a file
  4141.       ftouch     // update date/time of a file or marked files
  4142.  
  4143.  
  4144.   On-Event Functions
  4145.   ──────────────────
  4146.   To provide for an even higher degree of customization, the editor
  4147.   calls several event functions that 'notify' you when an important
  4148.   internal event has occurred, such as starting the editor, opening a
  4149.   file, etc. Using the macro language, you can write event handling
  4150.   functions which respond to these events.
  4151.  
  4152.   The 'onentry' and 'onexit' events are generated when an edit session
  4153.   is started and ended. Functions which respond to these events
  4154.   typically perform some initialization or cleanup tasks. For example:
  4155.  
  4156.     function onentry
  4157.       // 'onentry' in EXT.AML performs the following initializations:
  4158.       //   - open prompt and window history
  4159.       //   - open any command-line filespecs passed to this function
  4160.       //   - still no windows open? then do bootoptions
  4161.       //   - mouse setup
  4162.       //   - open key macro files
  4163.     end 
  4164.  
  4165.     function onexit
  4166.       // 'onexit' in EXT.AML performs the following cleanup tasks:
  4167.       //   - save prompt and window history
  4168.       //   - save key macros if record occurred
  4169.     end 
  4170.  
  4171.   The 'onopen' event is generated when a new file is loaded or a file
  4172.   manager window is created. Functions which respond to this event can
  4173.   perform a variety of customizations, such as setting the window object
  4174.   class, altering the window settings and the tab width based on the
  4175.   file extension, expanding tabs, changing the menus, or almost anything
  4176.   else you can think of. For example:
  4177.  
  4178.     object edit
  4179.        .
  4180.        .
  4181.       // an edit window has been opened..
  4182.       function onopen
  4183.          .
  4184.          .
  4185.         // if the window settings are not remembered from a previous
  4186.         // session, set them based on the file extension:
  4187.         if not getsettings then 
  4188.           case getext (getbufname)
  4189.  
  4190.             // for C or C++ files, turn on syntax highlighting,
  4191.             // autoindent, undo, and file backup
  4192.             when ".C", ".CPP". ".H"
  4193.               setting "XAUB" ON
  4194.  
  4195.             // for documents, turn on live word wrap, text translation,
  4196.             // autoindent, undo, and file backup
  4197.             when ".TXT", ".DOC"
  4198.               setting "LTAUB" ON
  4199.  
  4200.             // for all other extensions, use the configuration default
  4201.             otherwise 
  4202.               setting _DefaultSet ON
  4203.           end 
  4204.         end 
  4205.       end 
  4206.  
  4207.   The 'pass' builtin function can be used from within an on-event
  4208.   function to 'pass on' the event notification to the same on-event
  4209.   function in other objects.
  4210.  
  4211.  
  4212.   The following is a complete list of all the 'onevent' functions:
  4213.  
  4214.     builtin functions:
  4215.       oncompiling    // called while compiling a file
  4216.       onloading      // called while loading a file
  4217.       onprinting     // called while printing a file
  4218.       onsaving       // called while saving a file
  4219.  
  4220.     library functions:
  4221.       onalarm        // called to sound the PC speaker
  4222.       onclose        // called before closing a file or fmgr window
  4223.       oncomment      // returns language comments for a filename
  4224.       onentry        // called after starting the editor
  4225.       onexit         // called before exiting the editor
  4226.       onfocus        // called after switching to another file or window
  4227.       onfound        // called after a string is found
  4228.       onhotkey       // called after a filelist hotkey char is entered
  4229.       onopen         // called after loading a new file or fmgr window
  4230.       onscanning     // called while scanning files
  4231.       onsyntax       // returns a syntax object for a filename
  4232.  
  4233.     extension functions:
  4234.       onsave         // called before a file is saved
  4235.  
  4236.  
  4237.   Library Object Hierarchies
  4238.   ──────────────────────────
  4239.   In order to better understand the windowing behaviour of the editor,
  4240.   it is important to understand how some of the objects defined in the
  4241.   editor library (LIB.X) are organized.
  4242.  
  4243.   The editor library generally associates the objects it defines with
  4244.   one or more window types. For example, the object 'edit' is associated
  4245.   with edit windows, while the object 'edit_fmgr' is associated with
  4246.   both edit windows and file manager windows. This means that the object
  4247.   'edit' contains functions and variables that are only relevant to edit
  4248.   windows, while the object 'edit_fmgr' contains functions and variables
  4249.   which apply to both edit and file manager windows.
  4250.  
  4251.   This distinction also applies to event-handling functions. For example
  4252.   in the Aurora KBD.AML file, the <alt e> key performs the same action
  4253.   (display an open prompt) in both edit windows and file manager
  4254.   windows. Therefore, <alt e> is defined only once in the 'edit_fmgr'
  4255.   object, avoiding duplicate definitions in the 'edit' and 'fmgr'
  4256.   objects. Note that in order for this to work, the 'edit' object must
  4257.   be descended from the 'edit_fmgr' object. Thus when a key is pressed
  4258.   in an edit window, and the key definition is not found in the 'edit'
  4259.   object, the 'edit_fmgr' object is searched for the key definition.
  4260.  
  4261.   These are some of the object statements used to define objects and
  4262.   object hierarchies for editor windows in the editor library (LIB.X):
  4263.  
  4264.     object  a         (prf                  )
  4265.     object  mon       (a                    )
  4266.     object  win       (a mon                )
  4267.     object  prompt    (win                  )
  4268.     object  edit_fmgr (a win                )
  4269.     object  fmgr      (a edit_fmgr          )
  4270.     object  edit      (a prompt edit_fmgr   )
  4271.  
  4272.   The following is a partial graphical representation of the object
  4273.   hierarchy:
  4274.  
  4275.              prf
  4276.               │
  4277.               a                  // parent objects
  4278.               ├─── mon
  4279.        ┌──── win ────┐
  4280.     prompt         edit_fmgr
  4281.        └──┬──────────┘  │        // child objects
  4282.          edit          fmgr
  4283.  
  4284.  
  4285.   The following list shows the window types associated with each object:
  4286.  
  4287.     a          - all windows
  4288.     mon        - all windows
  4289.     win        - movable or sizable windows
  4290.     prompt     - edit windows, prompt windows, and edit controls
  4291.     edit_fmgr  - edit and file manager windows
  4292.     fmgr       - file manager windows
  4293.     edit       - edit windows
  4294.  
  4295.  
  4296.  
  4297.   Appendix A:  Key Event Names
  4298.   ────────────────────────────
  4299.   The following table lists the pre-defined keyboard event names
  4300.   generated or recognized by the editor. Enhanced keyboard keys are
  4301.   followed by an asterisk (*). Keyboard event names may be entered in
  4302.   mixed case.
  4303.  
  4304.  
  4305.   Normal Keys         Alt               Ctrl               Shift
  4306.   ───────────         ───               ────               ─────
  4307.  
  4308.   // non-function (typeable) keys
  4309.   // (arguments: 1=character, 2=keycode)
  4310.   <char>
  4311.  
  4312.   // any shiftkey pressed or released
  4313.   // (arguments: 1=old shift state, 2=new shift state)
  4314.   <shiftkey>
  4315.  
  4316.   // undefined or unrecognized keyboard event
  4317.   // (arguments: 1=keycode)
  4318.   <otherkey>
  4319.  
  4320.  
  4321.   // (arguments for all other keys: 1=keycode)
  4322.  
  4323.   // numeric keys
  4324.                       <alt 0>
  4325.                       <alt 1>
  4326.                       <alt 2>           <ctrl 2>
  4327.                       <alt 3>
  4328.                       <alt 4>
  4329.                       <alt 5>
  4330.                       <alt 6>           <ctrl 6>
  4331.                       <alt 7>
  4332.                       <alt 8>
  4333.                       <alt 9>
  4334.  
  4335.   // alphabetic keys
  4336.                       <alt a>           <ctrl a>
  4337.                       <alt b>           <ctrl b>
  4338.                       <alt c>           <ctrl c>
  4339.                       <alt d>           <ctrl d>
  4340.                       <alt e>           <ctrl e>
  4341.                       <alt f>           <ctrl f>
  4342.                       <alt g>           <ctrl g>
  4343.                       <alt h>           <ctrl h>
  4344.                       <alt i>           <ctrl i>
  4345.                       <alt j>           <ctrl j>
  4346.                       <alt k>           <ctrl k>
  4347.                       <alt l>           <ctrl l>
  4348.                       <alt m>           <ctrl m>
  4349.                       <alt n>           <ctrl n>
  4350.                       <alt o>           <ctrl o>
  4351.                       <alt p>           <ctrl p>
  4352.                       <alt q>           <ctrl q>
  4353.                       <alt r>           <ctrl r>
  4354.                       <alt s>           <ctrl s>
  4355.                       <alt t>           <ctrl t>
  4356.                       <alt u>           <ctrl u>
  4357.                       <alt v>           <ctrl v>
  4358.                       <alt w>           <ctrl w>
  4359.                       <alt x>           <ctrl x>
  4360.                       <alt y>           <ctrl y>
  4361.                       <alt z>           <ctrl z>
  4362.  
  4363.   // non-alphanumeric
  4364.                       <alt '>*
  4365.                       <alt ,>*
  4366.                       <alt ->           <ctrl ->
  4367.                       <alt .>*
  4368.                       <alt />*
  4369.                       <alt ;>*
  4370.                       <alt =>
  4371.                       <alt [>*          <ctrl [>
  4372.                       <alt \>*          <ctrl \>
  4373.                       <alt ]>*          <ctrl ]>
  4374.                       <alt `>*
  4375.  
  4376.   // function keys
  4377.   <f1>                <alt f1>          <ctrl f1>          <shift f1>
  4378.   <f2>                <alt f2>          <ctrl f2>          <shift f2>
  4379.   <f3>                <alt f3>          <ctrl f3>          <shift f3>
  4380.   <f4>                <alt f4>          <ctrl f4>          <shift f4>
  4381.   <f5>                <alt f5>          <ctrl f5>          <shift f5>
  4382.   <f6>                <alt f6>          <ctrl f6>          <shift f6>
  4383.   <f7>                <alt f7>          <ctrl f7>          <shift f7>
  4384.   <f8>                <alt f8>          <ctrl f8>          <shift f8>
  4385.   <f9>                <alt f9>          <ctrl f9>          <shift f9>
  4386.   <f10>               <alt f10>         <ctrl f10>         <shift f10>
  4387.   <f11>*              <alt f11>*        <ctrl f11>*        <shift f11>*
  4388.   <f12>*              <alt f12>*        <ctrl f12>*        <shift f12>*
  4389.  
  4390.   // special keys
  4391.   <backspace>         <alt backspace>*  <ctrl backspace>
  4392.   <enter>             <alt enter>*      <ctrl enter>
  4393.   <esc>               <alt esc>*
  4394.                                         <ctrl prtsc>
  4395.   <tab>               <alt tab>*        <ctrl tab>*        <shift tab>
  4396.  
  4397.   // keypad keys
  4398.   <del>               <alt del>*        <ctrl del>*        <shift del>
  4399.   <down>              <alt down>*       <ctrl down>*       <shift down>
  4400.   <end>               <alt end>*        <ctrl end>         <shift end>
  4401.   <home>              <alt home>*       <ctrl home>        <shift home>
  4402.   <ins>               <alt ins>*        <ctrl ins>*        <shift ins>
  4403.   <left>              <alt left>*       <ctrl left>        <shift left>
  4404.   <pgdn>              <alt pgup>*       <ctrl pgup>        <shift pgup>
  4405.   <pgup>              <alt pgdn>*       <ctrl pgdn>        <shift pgdn>
  4406.   <right>             <alt right>*      <ctrl right>       <shift right>
  4407.   <up>                <alt up>*         <ctrl up>*         <shift up>
  4408.   <center>*                             <ctrl center>*     <shift center>
  4409.  
  4410.   // grey keypad keys
  4411.   <grey*>             <alt grey*>*      <ctrl grey*>*
  4412.   <grey+>             <alt grey+>*      <ctrl grey+>*
  4413.   <grey->             <alt grey->*      <ctrl grey->*
  4414.                       <alt grey/>*      <ctrl grey/>*
  4415.   <greyenter>         <alt greyenter>*  <ctrl greyenter>*
  4416.  
  4417.  
  4418.  
  4419.   Appendix B:  Mouse Event Names
  4420.   ──────────────────────────────
  4421.   The following table lists the pre-defined mouse event names generated
  4422.   or recognized by the editor. Mouse event names may be entered in mixed
  4423.   case.
  4424.  
  4425.  
  4426.   Name             Action
  4427.   ────             ──────
  4428.   <lbutton>        left button down
  4429.   <lbuttonup>      left button up
  4430.   <rbutton>        right button down
  4431.   <rbuttonup>      right button up
  4432.   <cbutton>        center button down
  4433.   <cbuttonup>      center button up
  4434.  
  4435.   <move>           mouse movement
  4436.  
  4437.   <ldouble>        left button double click
  4438.   <rdouble>        right button double click
  4439.   <cdouble>        center button double click
  4440.  
  4441.   <ltriple>        left button triple click
  4442.   <rtriple>        right button triple click
  4443.   <ctriple>        center button triple click
  4444.  
  4445.   <chord>          mouse chord
  4446.  
  4447.